A. Cleaning the 5W data

This first section details an example of the code necessary for cleaning a 5W dataset in R. 5W data is typically messy and in wide format. Additionally, data wrangling is time consuming and an inefficient use of a specialist’s time. The code presented below intends to demonstrate that this monthly (or sometimes more frequent) occurence can be greatly automated, allowing for more timely and accurate analysis as well as creating the space for more tailored reporting.

 

1. Reading in the dataset

# specifying column types 
act_col_types <- c("date", "date", "text", "text","text","text",
                   "text","text","text","text","text","text","text",
                   "numeric", "numeric", "text","text","text",
                   "text","text","text", "numeric", "text", 
                   "date", "date", "text", "numeric", "numeric",
                   "logical", "numeric", "numeric", "numeric",
                   "numeric", "numeric", "numeric", "numeric",
                   "numeric", "numeric", "numeric", "numeric",
                   "numeric", "numeric", "numeric")

# you're gonna have to live with the error messages,
# since you can't slice before read_excel() argument

act1<- read_excel("database activities 5W.xlsx", 
                     sheet = "data", 
                     skip = 1, 
                     col_types = act_col_types) %>% 
  clean_names() %>% 
  remove_empty() %>% 
  slice(-c(1)) %>% # removes the second row
  slice(-c(12055)) # removes the grand total

1a. Renaming Columns

A glimpse() of the renamed dataset:

## Rows: 12,054
## Columns: 43
## $ fecha_reportado_cluster           <dttm> NA, NA, NA, NA, NA, NA, NA, NA, NA,~
## $ mes_reportado                     <dttm> 2020-01-31, 2020-01-31, 2020-01-31,~
## $ codigo_de_proyecto                <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
## $ nombre_del_proyecto               <chr> "Todos y Todas a la Escuela", "Todos~
## $ organizacion_lider                <chr> "UNICEF - Fondo de las Naciones Unid~
## $ organizacion_implementadora       <chr> "SOCIO 1", "SOCIO 1", "SOCIO 1", "SO~
## $ estado                            <chr> "Zulia", "Zulia", "Zulia", "Distrito~
## $ pcode1                            <chr> "VE23", "VE23", "VE23", "VE01", "VE0~
## $ municipio                         <chr> "Maracaibo", "Maracaibo", "Maracaibo~
## $ pcode2                            <chr> "VE2313", "VE2313", "VE2313", "VE010~
## $ parroquia                         <chr> "Luis Hurtado Higuera", "Luis Hurtad~
## $ pcode3                            <chr> "VE231312", "VE231312", "VE231312", ~
## $ ubicacion                         <chr> "E. T. Dr. Luis Razetti  Fe Y Alegrí~
## $ latitud                           <dbl> 10.596934, 10.596934, 10.596934, 10.~
## $ longitud                          <dbl> -71.66896, -71.66896, -71.66896, -66~
## $ actividad_full                    <chr> "CLEDU/CA2.09: Formación docente y o~
## $ actividad_codigo                  <chr> "CA2.09", "CA2.09", "CA2.09", "CA2.0~
## $ actividad_desc                    <chr> "Formación docente y otro personal e~
## $ actividad_codigo_desc             <chr> "CA2.09: Formación docente y otro pe~
## $ act_covid                         <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
## $ unidad                            <chr> "#Personas", "#Personas", "#Personas~
## $ cantidad_del_mes                  <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
## $ recurrente_beneficiarios          <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
## $ fecha_de_inicio                   <dttm> 2019-10-22, 2019-10-15, 2020-01-13,~
## $ fecha_prevista_finalizacion       <dttm> 2020-01-20, 2020-01-13, 2020-01-13,~
## $ estatus_actividad                 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
## $ total_beneficiarios               <dbl> 16, 13, 41, 2, 1, 25, 19, 19, 17, 17~
## $ check_beneficiaries               <dbl> 16, 13, 41, 2, 1, 25, 19, 19, 17, 17~
## $ t_f_ben                           <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ~
## $ percent_poblacion_indigena        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
## $ percent_personas_con_discapacidad <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
## $ m_0_3                             <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ m_3_6                             <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ m_7_12                            <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ m_12_17                           <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ m_18_19                           <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ f_0_3                             <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ f_3_6                             <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ f_7_12                            <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ f_12_17                           <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ f_18_19                           <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ f_mayores_de_19                   <dbl> 11, 4, 41, 2, 1, 20, 10, 10, 5, 8, 3~
## $ m_mayores_de_19                   <dbl> 5, 9, 0, 0, 0, 5, 9, 9, 12, 9, 13, 1~

 

2. String Manipulation and Recoding

2a. Removing accents and standardising case

Whilst it is true when some people say that if you remove tildes and other diacritical marks, it it no longer becomes Spanish. However, it must be said that implementing partners don’t care and have included a wide variety of spellings. I would say that remove all accent marks is necessary to continue working with the dataset.

# function to remove accents
rm_accent <- function(colns){
  colns <- stri_trans_general(colns, "Latin-ASCII")
}

# removing accents
# and str_to_upper() since R is case-sensitive
act1 <- act1 %>% 
  mutate(estado    = rm_accent(str_to_upper(estado)), 
         municipio = rm_accent(str_to_upper(municipio)),
         parroquia = rm_accent(str_to_upper(parroquia)),
         ubicacion = rm_accent(str_to_upper(ubicacion)),
         actividad_desc = rm_accent(str_to_upper(actividad_desc)))

2b. Recoding erroneous data

These should just be dropdown menus; partners should also be informed that blanks will be treated as FALSE. Additionally, a new date column just with the month is mutated, as the mes_reportado column has some months with multiple reporting dates.

# recoding 
act1 <- act1 %>% 
  mutate(recurrente_beneficiarios = 
           recode(recurrente_beneficiarios, 
            "no" = FALSE, "No" = FALSE, "Si" = TRUE, "si" = TRUE, "sí" = TRUE, "Sí" = TRUE),
         act_covid = recode(act_covid, 
            "no" = FALSE, "No" = FALSE, "Si" = TRUE, "si" = TRUE, "sí" = TRUE, "Sí" = TRUE)) %>% 
  replace_na(list(recurrente_beneficiarios = FALSE, act_covid = FALSE)) 

# recoding estatus_actividad
act1$estatus_actividad <- act1$estatus_actividad %>% 
  str_replace_all(c("En ejecucion" = "ejecucion", 
                    "en ejecución" = "ejecucion", 
                    "en Ejecución" = "ejecucion",
                    "En ejecución" = "ejecucion",
                    "En Ejecución" = "ejecucion",
                    "finalizada" = "finalizada",
                    "Finalizada" = "finalizada"))

# create a new variable of last day of month only 
act1$mes_solo <- ceiling_date(act1$mes_reportado, "month") - days(1)

 

3. Cleaning locations

3a. Read in locations.csv

And check if you need to update it.

locations <- read_csv("locations.csv") %>%
  mutate(estado    = rm_accent(str_to_upper(estado)), # just to make sure 
         municipio = rm_accent(str_to_upper(municipio)),
         parroquia = rm_accent(str_to_upper(parroquia)),
         ubicacion = rm_accent(str_to_upper(ubicacion)))

Maybe we should add new pcodes for “todo municipio” and “todo estado”; will they be abused?

# see if you need to update locations 
# new locations not in locations.csv will be caught by the anti-join()
 locations_add <- act1 %>% 
   select(estado, pcode1, municipio, pcode2, parroquia, pcode3, ubicacion,
          latitud, longitud) %>% 
   distinct() %>% 
   anti_join(locations, by = "ubicacion")

3b. Splitting the dataset into clean and dirty

# splitting into two datasets, one clean one dirty. 
adm_dirty <- act1 %>% 
  filter(is.na(estado) | is.na(pcode1) |
         is.na(municipio) | is.na(pcode2) |
         is.na(parroquia) | is.na(pcode3))

adm_clean <- act1 %>% 
  filter(!is.na(estado) & !is.na(pcode1) &
         !is.na(municipio) & !is.na(pcode2) &
         !is.na(parroquia) & !is.na(pcode3)) 

3c. Fill in missing values with coalesce()

The locations reference dataset is used to clean adm_dirty and rewrite it. The distinct() call at the end is to ensure that no duplicates are included as the left_join() argument will produce duplicates (still not sure how to control this). After which, adm_clean and adm_dirty are combined into act2.

# filling in missing values
adm_dirty <- adm_dirty %>% 
  left_join(locations, by = "ubicacion") %>% 
  mutate(estado    = coalesce(estado.x, estado.y),
         pcode1    = coalesce(pcode1.x, pcode1.y),
         municipio = coalesce(municipio.x, municipio.y),
         pcode2    = coalesce(pcode2.x, pcode2.y),
         parroquia = coalesce(parroquia.x, parroquia.y),
         pcode3    = coalesce(pcode3.x, pcode3.y)) %>% 
  select(-estado.x, -estado.y, -pcode1.x, -pcode1.y,
         -municipio.x, -municipio.y, -pcode2.x, -pcode2.y,
         -parroquia.x, -parroquia.y, -pcode3.x, -pcode3.y) %>% 
  distinct() # removing duplicate rows from the join 

# bind_rows() does not care about column sequence 
# but put adm_clean first so that the original order is preserved
act2 <- bind_rows(adm_clean, adm_dirty)

3d. Error checking the join

printing total beneficiaries for act1 and act2, followed by nrow() for both.

##          [,1]
## [1,] 28965878
## [2,] 28965878
## [3,]    12054
## [4,]    12054

 

4. Beneficiary disaggregation

This is to check that total_beneficiarios is equal to the sum of all disaggregated columns. First, we mutate a new column by summing all the disaggregated beneficiaries and calling it total_ben_check. Then, we mutate a new column in thr dataset called no_esp_ben or beneficiarios no especificados so that we maintain the un-disaggregated beneficiaries without polluting the rest of the dataset.

# mutating bencheck and unspecified beneficiaries columns 
act2 <- act2 %>% 
  mutate(total_ben_check = select(., m_0_3:m_mayores_de_19) %>%  rowSums(na.rm = TRUE), 
         no_esp_ben      = round(total_beneficiarios) - round(total_ben_check)) 

Next, we print rows where the sum of disaggregated beneficiaries (total_ben_check) do not match the totals reported in the total_beneficiarios column so that we can return to the relevant parties for follow up.

Undisaggregated beneficiaries
organizacion_implementadora actividad_desc ubicacion total_ben_check total_beneficiarios no_esp_ben
SOCIO 2 PROMOCION MENSAJES CLAVES PARA LA COMUNIDAD ESCOLAR U.E.C. DIVINA PASTORA (CATEDRAL) 0 244 244
SOCIO 4 INICIATIVAS PARA REINSERCION EDUCATIVA DE NNA FUERA DE LA ESCUELA U.E. SAN JOSE DE COTIZA 18 26 8
SOCIO 6 FORMACION DOCENTE Y OTRO PERSONAL EDUCATIVO MINISTERIO DEL PODER POPULAR PARA LA EDUCACION 0 398 398
SOCIO 6 FORMACION DOCENTE Y OTRO PERSONAL EDUCATIVO CLUSTER DE EDUCACION 0 146 146

 

5. Outputs

5a. Cleaned wide version

# timestamp for all the files to be written below
now <- Sys.time()

For submissions to OCHA, this one aligns with their format

# turn on eval if you want the file
filename_wide <- paste0(format(now, "%y%m%d_%H%M_"), "5W_wide.csv")
write_csv(act2, filename_wide)

5b. Unique beneficiaries

This section pivots the dataset longer into tidy data, with one observation per instance of age and sex; this is necessary for easy plotting and analysis. Additionally, rows with no beneficiaries are filtered out.

The dataset u_ben is created by taking the highest number of beneficiaries by age and sex group by location of all non-recurrent beneficiaries. The columns are then filtered down to create a more usable dataset. We will use this dataset for any operations related to unique beneficiaries (individuals), including comparisons with census data to determine reach and coverage as well as geographic analysis. We drop activity information from this dataset as it only contains the max of per disaggregation group per location anyway.

# pivoting longer and creating new dataframe
u_ben <- act2 %>% 
  select(-t_f_ben, -total_ben_check) %>% # remember to drop them
  relocate(mes_solo) %>% # moves mes_solo to the first variable
  pivot_longer(m_0_3:no_esp_ben, 
               names_to = "desagregacion", values_to = "beneficiarios") %>% 
  filter(recurrente_beneficiarios == FALSE) %>%
  filter(beneficiarios != 0) %>% # empty cells are 0 in the 5W table
  group_by(ubicacion, desagregacion) %>% 
  slice(which.max(beneficiarios)) %>% 
  ungroup() %>% 
  select(mes_solo, estado, pcode1, municipio, pcode2,parroquia, pcode3, 
         ubicacion, latitud, longitud,
         desagregacion, beneficiarios)
# writing csv of u_ben with datestamp
# turn on eval if you want the file 
filename_u_ben <- paste0(format(now, "%y%m%d_%H%M_"), "u_ben.csv")
write_csv(u_ben, filename_u_ben)

5c. Beneficiaries by activity

The dataset act_ben is for activity-wise analysis. Only the rows marked as recurrente_beneficiarios == FALSE have been selected. The first instance of recurring beneficiaires is marked FALSE, with all subsequent entries being marked TRUE. Similar to u_ben, it has also been pivoted longer into tidy data.

Please not that there is double counting in this dataset as specific beneficiaries might been reached by more than one activity. For geographic analysis, please use u_ben.

# This is the dataset for beneficiaries
act_ben <- act2 %>%
  select(-t_f_ben, -total_ben_check) %>% # remember to drop them
  relocate(mes_solo) %>% # moves mes_solo to the first variable
  filter(recurrente_beneficiarios == FALSE) %>%
  pivot_longer(m_0_3:no_esp_ben, 
               names_to = "desagregacion", values_to = "beneficiarios") %>% 
  filter(beneficiarios != 0) %>% # empty cells are 0 in the 5W table
  group_by(ubicacion, desagregacion) %>% 
  select(mes_solo, nombre_del_proyecto, organizacion_implementadora, 
         estado, pcode1, municipio, pcode2, parroquia, pcode3, 
         ubicacion, latitud, longitud,
         actividad_codigo, actividad_desc, act_covid,
         desagregacion, beneficiarios)
# writing csv act_ben with datestamp
# turn on eval if you want the file 
filename_act_ben <- paste0(format(now, "%y%m%d_%H%M_"), "act_ben.csv")
write_csv(act_ben, filename_act_ben)

5d. Comparing u_ben, act_ben and difference

Please note that this still has that radio messaging activity lumped in with the totals.

<<<<<<< HEAD
##          [,1]
## [1,]  3660609
## [2,]  5673040
## [3,] -2012431
=======
##      [,1]        
## [1,] "3,660,609" 
## [2,] "5,673,040" 
## [3,] "-2,012,431"
>>>>>>> e20677e90f322826cdd69436c08e7989a6156c0b

 

B. Reporting on the 5W data

 

This is an entirely automated report – all charts and tables, as well as all figures within the report have been generated from the data, with no manual input. This report makes use of the outputs of the 5W_cleaning section above. This set of 5W data pertains to the Education Cluster in Venezuela and has had partner information removed. Code will not be shown in this section – you can download the Rmd at the top-left corner of this doucument.

 

1. Summary of beneficiaries by activity, with sex ratio

actividad total percent_of_total male female sex_ratio
DISTRIBUCION DE KITS DE MATERIALES ESCOLARES 471,568 50.91 232,197 239,372 0.97
ALIMENTACION ESCOLAR 156,472 16.89 72,035 84,437 0.85
EDUCACION A DISTANCIA 132,258 14.28 64,240 68,018 0.94
APOYO PSICOEDUCATIVO PARA NNA 120,887 13.05 54,859 66,028 0.83
FORMACION DOCENTE Y OTRO PERSONAL EDUCATIVO 17,238 1.86 3,470 13,224 0.26
ACTIVIDADES CON ADOLESCENTES Y JOVENES DE NIVELACION, HABILIDADES PARA LA VIDA Y CAPACITACION TECNICA 14,016 1.51 6,336 7,680 0.82
BECAS Y OTROS INCENTIVOS PARA DOCENTES Y PERSONAL 5,744 0.62 1,572 4,172 0.38
ACTIVIDADES RECREATIVAS 4,317 0.47 1,998 2,319 0.86
INICIATIVAS PARA REINSERCION EDUCATIVA DE NNA FUERA DE LA ESCUELA 3,869 0.42 2,114 1,755 1.2

A total of 728,408 individuals have been reached to date. In terms of frequencies (inclusive of double counting), 926,369 have been reached.

Additionally, the 4,746,671 beneficiary frequencies reached by the activity PROMOCION MENSAJES CLAVES PARA LA COMUNIDAD ESCOLAR have been removed from the totals in this report as the activity consists of solely radio messaging.

 

2. Beneficiaries by age group

figures are unique beneficiaries/individuals

 

2a. Beneficiaries by age compared to 2017 Enrollment

With reference to the 2017 Matricula dataset, we can see that the Education programme has reached an overall average of 9% of schoolgoing children aged 3-17 nationwide. Children aged 3-17 consitute 88% of all UNICEF beneficiaries.

Edad grupo beneficiarios matricula2017 percent_total
3-6 121,169 1,438,475 8.423
7-12 352,808 3,252,505 10.85
12-17 169,771 2,205,724 7.697

 

3. Changes since previous month

The number of individuals reached has increased by 175,005 in the past month, reaching a total of 728,408. The number of beneficiary frequencies reached has increased by 218,443 in the same period, reaching a total of 926,369.

 

3a. Progress by activity by month

mouse over to see details

<<<<<<< HEAD
=======
>>>>>>> e20677e90f322826cdd69436c08e7989a6156c0b

Progress in recent months has largely been due to the distribution of education kits and distance learning.

 

4. Summaries by geography

4a. Beneficiaries by state

 

4b. Number of schools by state

A total of 2,229 schools have been reached by UNICEF; 44% are from Miranda and Zulia alone.

 

4c. Scatterplot of municipalities

logarithmic scale; larger points indicate more beneficiaries reached, darker blues indicate more activity types

mouse over municipalities to see beneficiaries and distinct activities

A total of 110 municipalities were reached by the UNICEF Education programme.

<<<<<<< HEAD
=======
>>>>>>> e20677e90f322826cdd69436c08e7989a6156c0b

 

4d. Top 10 municipalities by reach and coverage

by beneficiaries
estado municipio beneficiarios
DISTRITO CAPITAL LIBERTADOR 80482
MIRANDA SUCRE 59176
ZULIA MARACAIBO 55370
BOLIVAR CARONI 37908
ZULIA SAN FRANCISCO 29369
AMAZONAS ATURES 22430
LARA IRIBARREN 21977
BOLIVAR HERES 18293
DELTA AMACURO TUCUPITA 17953
BOLIVAR CEDENO 15681
by coverage
estado municipio coverage_percent
TACHIRA FERNANDEZ FEO 87
TACHIRA AYACUCHO 79
ZULIA MACHIQUES DE PERIJA 79
AMAZONAS AUTONOMO AUTANA 76
TACHIRA SAMUEL DARIO MALDONADO 75
TACHIRA PANAMERICANO 72
MIRANDA PLAZA 68
TACHIRA INDEPENDENCIA 68
TACHIRA JUNIN 65
MIRANDA EL HATILLO 64

Together, the 10 municipalities with the highest reach (above left) form 49% of the 728,408 beneficiaries reached. The average coverage of the school-age population in the municipalities where UNICEF is present is 20%. Coverage refers to the percentage of enrolled children (aged 3-17 years) reached by UNICEF.

 

4e. Histogram of Coverage

Below is a histogram of munciipalities where UNICEF is present showing the coverage of enrolled children (aged 3-17). Of note, we have reached 10% or less of the population in 55 out of the 110 in which we operate. This is in addition to the 226 where no UNICEF Education activities have occurred.

 

5. Reports about partners

5a. Summary by partner

<<<<<<< HEAD
=======
>>>>>>> e20677e90f322826cdd69436c08e7989a6156c0b

 

5b. Number of activity types implemented by each partner

partner SOCIO 2 SOCIO 1 SOCIO 4 SOCIO 5 UNICEF SOCIO 3 SOCIO 6 SOCIO 7 SOCIO 10 SOCIO 8
act_types 9 8 8 6 6 4 2 2 1 1

 

5c. Partners’ progress over time

mouse over for details

<<<<<<< HEAD
=======
>>>>>>> e20677e90f322826cdd69436c08e7989a6156c0b

 

5d. Summary table of partners’ achievements

organizacion_implementadora beneficiarios percent_of_total male female sex_ratio municipalities
UNICEF 353,944 38.21 168,281 185,664 0.91 74
SOCIO 1 160,260 17.3 79,958 80,302 1 92
SOCIO 2 145,997 15.76 65,390 80,607 0.81 51
SOCIO 5 113,845 12.29 50,511 63,334 0.8 10
SOCIO 4 86,074 9.29 42,534 43,540 0.98 17
SOCIO 7 31,322 3.38 14,750 16,572 0.89 10
SOCIO 8 29,471 3.18 15,379 14,092 1.09 17
SOCIO 10 2,461 0.27 1,151 1,310 0.88 1
SOCIO 3 2,423 0.26 862 1,561 0.55 3
SOCIO 6 572 0.06 5 23 0.22 7

 

6. Maps and reference table

 

6a. Maps at municipal level

 

6b. Reference table – municipal level

use UNICEF_present to filter to municipalities where the Education programme operates

CA01.05 Promocion de mensajes claves para la comunidad escolar is not included

<<<<<<< HEAD
=======
>>>>>>> e20677e90f322826cdd69436c08e7989a6156c0b
<<<<<<< HEAD
LS0tDQp0aXRsZTogIkNsZWFuaW5nIGFuZCBSZXBvcnRpbmcgb24gRWR1Y2F0aW9uIDVXIGRhdGEgZnJvbSBWZW5lenVlbGEiDQphdXRob3I6ICJTZWFuIE5nIg0KZGF0ZTogIjEyIE5vdmVtYmVyLCAyMDIxIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRvY19kZXB0aDogNA0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiByZWFkYWJsZQ0KLS0tDQoNCiMgQS4gQ2xlYW5pbmcgdGhlIDVXIGRhdGENCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGggPSA5LjUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShzdHJpbmdyKQ0KbGlicmFyeShzdHJpbmdpKQ0KbGlicmFyeShwYW5kZXIpDQpsaWJyYXJ5KHNjYWxlcykNCmxpYnJhcnkoZm9yY2F0cykNCmxpYnJhcnkoamFuaXRvcikNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShnZ21hcCkNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KHBhdGNod29yaykNCmxpYnJhcnkobWFwdG9vbHMpDQpsaWJyYXJ5KGdnZm9yY2UpDQpsaWJyYXJ5KGdndGhlbWVzKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KERUKQ0KbGlicmFyeSh0aW55dGV4KQ0KDQojIHRhYmxlcyBhbGwgaW4gb25lIHJvdw0KcGFuZGVyT3B0aW9ucygndGFibGUuc3BsaXQudGFibGUnLCBJbmYpDQoNCiMgdGhvdXNhbmRzIHNlcGFyYXRvcg0KcGFuZGVyT3B0aW9ucygiYmlnLm1hcmsiLCAiLCIpDQoNCmBgYA0KDQoNCj4gVGhpcyBmaXJzdCBzZWN0aW9uIGRldGFpbHMgYW4gZXhhbXBsZSBvZiB0aGUgY29kZSBuZWNlc3NhcnkgZm9yIGNsZWFuaW5nIGEgNVcgZGF0YXNldCBpbiBSLiA1VyBkYXRhIGlzIHR5cGljYWxseSBtZXNzeSBhbmQgaW4gd2lkZSBmb3JtYXQuIEFkZGl0aW9uYWxseSwgZGF0YSB3cmFuZ2xpbmcgaXMgdGltZSBjb25zdW1pbmcgYW5kIGFuIGluZWZmaWNpZW50IHVzZSBvZiBhIHNwZWNpYWxpc3QncyB0aW1lLiBUaGUgY29kZSBwcmVzZW50ZWQgYmVsb3cgaW50ZW5kcyB0byBkZW1vbnN0cmF0ZSB0aGF0IHRoaXMgbW9udGhseSAob3Igc29tZXRpbWVzIG1vcmUgZnJlcXVlbnQpIG9jY3VyZW5jZSBjYW4gYmUgZ3JlYXRseSBhdXRvbWF0ZWQsIGFsbG93aW5nIGZvciBtb3JlIHRpbWVseSBhbmQgYWNjdXJhdGUgYW5hbHlzaXMgYXMgd2VsbCBhcyBjcmVhdGluZyB0aGUgc3BhY2UgZm9yIG1vcmUgdGFpbG9yZWQgcmVwb3J0aW5nLiAgDQoNCiZuYnNwOw0KDQojIyAxLiBSZWFkaW5nIGluIHRoZSBkYXRhc2V0DQoNCmBgYHtyIHJlYWRpbmctaW4teGxzeCwgZWNobz1UUlVFfQ0KIyBzcGVjaWZ5aW5nIGNvbHVtbiB0eXBlcyANCmFjdF9jb2xfdHlwZXMgPC0gYygiZGF0ZSIsICJkYXRlIiwgInRleHQiLCAidGV4dCIsInRleHQiLCJ0ZXh0IiwNCiAgICAgICAgICAgICAgICAgICAidGV4dCIsInRleHQiLCJ0ZXh0IiwidGV4dCIsInRleHQiLCJ0ZXh0IiwidGV4dCIsDQogICAgICAgICAgICAgICAgICAgIm51bWVyaWMiLCAibnVtZXJpYyIsICJ0ZXh0IiwidGV4dCIsInRleHQiLA0KICAgICAgICAgICAgICAgICAgICJ0ZXh0IiwidGV4dCIsInRleHQiLCAibnVtZXJpYyIsICJ0ZXh0IiwgDQogICAgICAgICAgICAgICAgICAgImRhdGUiLCAiZGF0ZSIsICJ0ZXh0IiwgIm51bWVyaWMiLCAibnVtZXJpYyIsDQogICAgICAgICAgICAgICAgICAgImxvZ2ljYWwiLCAibnVtZXJpYyIsICJudW1lcmljIiwgIm51bWVyaWMiLA0KICAgICAgICAgICAgICAgICAgICJudW1lcmljIiwgIm51bWVyaWMiLCAibnVtZXJpYyIsICJudW1lcmljIiwNCiAgICAgICAgICAgICAgICAgICAibnVtZXJpYyIsICJudW1lcmljIiwgIm51bWVyaWMiLCAibnVtZXJpYyIsDQogICAgICAgICAgICAgICAgICAgIm51bWVyaWMiLCAibnVtZXJpYyIsICJudW1lcmljIikNCg0KIyB5b3UncmUgZ29ubmEgaGF2ZSB0byBsaXZlIHdpdGggdGhlIGVycm9yIG1lc3NhZ2VzLA0KIyBzaW5jZSB5b3UgY2FuJ3Qgc2xpY2UgYmVmb3JlIHJlYWRfZXhjZWwoKSBhcmd1bWVudA0KDQphY3QxPC0gcmVhZF9leGNlbCgiZGF0YWJhc2UgYWN0aXZpdGllcyA1Vy54bHN4IiwgDQogICAgICAgICAgICAgICAgICAgICBzaGVldCA9ICJkYXRhIiwgDQogICAgICAgICAgICAgICAgICAgICBza2lwID0gMSwgDQogICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBhY3RfY29sX3R5cGVzKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICByZW1vdmVfZW1wdHkoKSAlPiUgDQogIHNsaWNlKC1jKDEpKSAlPiUgIyByZW1vdmVzIHRoZSBzZWNvbmQgcm93DQogIHNsaWNlKC1jKDEyMDU1KSkgIyByZW1vdmVzIHRoZSBncmFuZCB0b3RhbA0KDQpgYGANCg0KIyMjIDFhLiBSZW5hbWluZyBDb2x1bW5zIA0KDQo+IEEgYGdsaW1wc2UoKWAgb2YgdGhlIHJlbmFtZWQgZGF0YXNldDoNCg0KYGBge3J9DQphY3RfbmFtZXMgPC0gYygiZmVjaGFfcmVwb3J0YWRvX2NsdXN0ZXIiLA0KICAgICAgICAgICAgICAgIm1lc19yZXBvcnRhZG8iLA0KICAgICAgICAgICAgICAgImNvZGlnb19kZV9wcm95ZWN0byIsDQogICAgICAgICAgICAgICAibm9tYnJlX2RlbF9wcm95ZWN0byIsDQogICAgICAgICAgICAgICAib3JnYW5pemFjaW9uX2xpZGVyIiwNCiAgICAgICAgICAgICAgICJvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEiLA0KICAgICAgICAgICAgICAgImVzdGFkbyIsDQogICAgICAgICAgICAgICAicGNvZGUxIiwNCiAgICAgICAgICAgICAgICJtdW5pY2lwaW8iLA0KICAgICAgICAgICAgICAgInBjb2RlMiIsDQogICAgICAgICAgICAgICAicGFycm9xdWlhIiwNCiAgICAgICAgICAgICAgICJwY29kZTMiLA0KICAgICAgICAgICAgICAgInViaWNhY2lvbiIsDQogICAgICAgICAgICAgICAibGF0aXR1ZCIsDQogICAgICAgICAgICAgICAibG9uZ2l0dWQiLA0KICAgICAgICAgICAgICAgImFjdGl2aWRhZF9mdWxsIiwNCiAgICAgICAgICAgICAgICJhY3RpdmlkYWRfY29kaWdvIiwNCiAgICAgICAgICAgICAgICJhY3RpdmlkYWRfZGVzYyIsDQogICAgICAgICAgICAgICAiYWN0aXZpZGFkX2NvZGlnb19kZXNjIiwNCiAgICAgICAgICAgICAgICJhY3RfY292aWQiLA0KICAgICAgICAgICAgICAgInVuaWRhZCIsDQogICAgICAgICAgICAgICAiY2FudGlkYWRfZGVsX21lcyIsDQogICAgICAgICAgICAgICAicmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zIiwNCiAgICAgICAgICAgICAgICJmZWNoYV9kZV9pbmljaW8iLA0KICAgICAgICAgICAgICAgImZlY2hhX3ByZXZpc3RhX2ZpbmFsaXphY2lvbiIsDQogICAgICAgICAgICAgICAiZXN0YXR1c19hY3RpdmlkYWQiLA0KICAgICAgICAgICAgICAgInRvdGFsX2JlbmVmaWNpYXJpb3MiLA0KICAgICAgICAgICAgICAgImNoZWNrX2JlbmVmaWNpYXJpZXMiLA0KICAgICAgICAgICAgICAgInRfZl9iZW4iLA0KICAgICAgICAgICAgICAgInBlcmNlbnRfcG9ibGFjaW9uX2luZGlnZW5hIiwNCiAgICAgICAgICAgICAgICJwZXJjZW50X3BlcnNvbmFzX2Nvbl9kaXNjYXBhY2lkYWQiLA0KICAgICAgICAgICAgICAgIm1fMF8zIiwNCiAgICAgICAgICAgICAgICJtXzNfNiIsDQogICAgICAgICAgICAgICAibV83XzEyIiwNCiAgICAgICAgICAgICAgICJtXzEyXzE3IiwNCiAgICAgICAgICAgICAgICJtXzE4XzE5IiwNCiAgICAgICAgICAgICAgICJmXzBfMyIsDQogICAgICAgICAgICAgICAiZl8zXzYiLA0KICAgICAgICAgICAgICAgImZfN18xMiIsDQogICAgICAgICAgICAgICAiZl8xMl8xNyIsDQogICAgICAgICAgICAgICAiZl8xOF8xOSIsDQogICAgICAgICAgICAgICAiZl9tYXlvcmVzX2RlXzE5IiwNCiAgICAgICAgICAgICAgICJtX21heW9yZXNfZGVfMTkiKQ0KDQojIHJlbmFtZWQgDQpuYW1lcyhhY3QxKSA8LSBhY3RfbmFtZXMNCg0KZ2xpbXBzZShhY3QxKQ0KYGBgDQoNCiZuYnNwOw0KDQojIyAyLiBTdHJpbmcgTWFuaXB1bGF0aW9uIGFuZCBSZWNvZGluZyANCg0KIyMjIDJhLiBSZW1vdmluZyBhY2NlbnRzIGFuZCBzdGFuZGFyZGlzaW5nIGNhc2UNCg0KPiBXaGlsc3QgaXQgaXMgdHJ1ZSB3aGVuIHNvbWUgcGVvcGxlIHNheSB0aGF0IGlmIHlvdSByZW1vdmUgdGlsZGVzIGFuZCBvdGhlciBkaWFjcml0aWNhbCBtYXJrcywgaXQgaXQgbm8gbG9uZ2VyIGJlY29tZXMgU3BhbmlzaC4gSG93ZXZlciwgaXQgbXVzdCBiZSBzYWlkIHRoYXQgaW1wbGVtZW50aW5nIHBhcnRuZXJzIGRvbid0IGNhcmUgYW5kIGhhdmUgaW5jbHVkZWQgYSB3aWRlIHZhcmlldHkgb2Ygc3BlbGxpbmdzLiBJIHdvdWxkIHNheSB0aGF0IHJlbW92ZSBhbGwgYWNjZW50IG1hcmtzIGlzIG5lY2Vzc2FyeSB0byBjb250aW51ZSB3b3JraW5nIHdpdGggdGhlIGRhdGFzZXQuIA0KDQpgYGB7ciByZW1vdmUtYWNjZW50cywgZWNobz1UUlVFfQ0KIyBmdW5jdGlvbiB0byByZW1vdmUgYWNjZW50cw0Kcm1fYWNjZW50IDwtIGZ1bmN0aW9uKGNvbG5zKXsNCiAgY29sbnMgPC0gc3RyaV90cmFuc19nZW5lcmFsKGNvbG5zLCAiTGF0aW4tQVNDSUkiKQ0KfQ0KDQojIHJlbW92aW5nIGFjY2VudHMNCiMgYW5kIHN0cl90b191cHBlcigpIHNpbmNlIFIgaXMgY2FzZS1zZW5zaXRpdmUNCmFjdDEgPC0gYWN0MSAlPiUgDQogIG11dGF0ZShlc3RhZG8gICAgPSBybV9hY2NlbnQoc3RyX3RvX3VwcGVyKGVzdGFkbykpLCANCiAgICAgICAgIG11bmljaXBpbyA9IHJtX2FjY2VudChzdHJfdG9fdXBwZXIobXVuaWNpcGlvKSksDQogICAgICAgICBwYXJyb3F1aWEgPSBybV9hY2NlbnQoc3RyX3RvX3VwcGVyKHBhcnJvcXVpYSkpLA0KICAgICAgICAgdWJpY2FjaW9uID0gcm1fYWNjZW50KHN0cl90b191cHBlcih1YmljYWNpb24pKSwNCiAgICAgICAgIGFjdGl2aWRhZF9kZXNjID0gcm1fYWNjZW50KHN0cl90b191cHBlcihhY3RpdmlkYWRfZGVzYykpKQ0KDQpgYGANCg0KIyMjIDJiLiBSZWNvZGluZyBlcnJvbmVvdXMgZGF0YQ0KDQo+IFRoZXNlIHNob3VsZCBqdXN0IGJlIGRyb3Bkb3duIG1lbnVzOyBwYXJ0bmVycyBzaG91bGQgYWxzbyBiZSBpbmZvcm1lZCB0aGF0IGJsYW5rcyB3aWxsIGJlIHRyZWF0ZWQgYXMgRkFMU0UuIEFkZGl0aW9uYWxseSwgYSBuZXcgZGF0ZSBjb2x1bW4ganVzdCB3aXRoIHRoZSBtb250aCBpcyBtdXRhdGVkLCBhcyB0aGUgYG1lc19yZXBvcnRhZG9gIGNvbHVtbiBoYXMgc29tZSBtb250aHMgd2l0aCBtdWx0aXBsZSByZXBvcnRpbmcgZGF0ZXMuIA0KDQpgYGB7ciByZWNvZGluZywgZWNobz1UUlVFfQ0KIyByZWNvZGluZyANCmFjdDEgPC0gYWN0MSAlPiUgDQogIG11dGF0ZShyZWN1cnJlbnRlX2JlbmVmaWNpYXJpb3MgPSANCiAgICAgICAgICAgcmVjb2RlKHJlY3VycmVudGVfYmVuZWZpY2lhcmlvcywgDQogICAgICAgICAgICAibm8iID0gRkFMU0UsICJObyIgPSBGQUxTRSwgIlNpIiA9IFRSVUUsICJzaSIgPSBUUlVFLCAic8OtIiA9IFRSVUUsICJTw60iID0gVFJVRSksDQogICAgICAgICBhY3RfY292aWQgPSByZWNvZGUoYWN0X2NvdmlkLCANCiAgICAgICAgICAgICJubyIgPSBGQUxTRSwgIk5vIiA9IEZBTFNFLCAiU2kiID0gVFJVRSwgInNpIiA9IFRSVUUsICJzw60iID0gVFJVRSwgIlPDrSIgPSBUUlVFKSkgJT4lIA0KICByZXBsYWNlX25hKGxpc3QocmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zID0gRkFMU0UsIGFjdF9jb3ZpZCA9IEZBTFNFKSkgDQoNCiMgcmVjb2RpbmcgZXN0YXR1c19hY3RpdmlkYWQNCmFjdDEkZXN0YXR1c19hY3RpdmlkYWQgPC0gYWN0MSRlc3RhdHVzX2FjdGl2aWRhZCAlPiUgDQogIHN0cl9yZXBsYWNlX2FsbChjKCJFbiBlamVjdWNpb24iID0gImVqZWN1Y2lvbiIsIA0KICAgICAgICAgICAgICAgICAgICAiZW4gZWplY3VjacOzbiIgPSAiZWplY3VjaW9uIiwgDQogICAgICAgICAgICAgICAgICAgICJlbiBFamVjdWNpw7NuIiA9ICJlamVjdWNpb24iLA0KICAgICAgICAgICAgICAgICAgICAiRW4gZWplY3VjacOzbiIgPSAiZWplY3VjaW9uIiwNCiAgICAgICAgICAgICAgICAgICAgIkVuIEVqZWN1Y2nDs24iID0gImVqZWN1Y2lvbiIsDQogICAgICAgICAgICAgICAgICAgICJmaW5hbGl6YWRhIiA9ICJmaW5hbGl6YWRhIiwNCiAgICAgICAgICAgICAgICAgICAgIkZpbmFsaXphZGEiID0gImZpbmFsaXphZGEiKSkNCg0KIyBjcmVhdGUgYSBuZXcgdmFyaWFibGUgb2YgbGFzdCBkYXkgb2YgbW9udGggb25seSANCmFjdDEkbWVzX3NvbG8gPC0gY2VpbGluZ19kYXRlKGFjdDEkbWVzX3JlcG9ydGFkbywgIm1vbnRoIikgLSBkYXlzKDEpDQpgYGANCg0KJm5ic3A7DQoNCiMjIDMuIENsZWFuaW5nIGxvY2F0aW9ucyANCg0KIyMjIDNhLiBSZWFkIGluIGBsb2NhdGlvbnMuY3N2YA0KDQo+IEFuZCBjaGVjayBpZiB5b3UgbmVlZCB0byB1cGRhdGUgaXQuIA0KDQpgYGB7ciByZWFkLWxvY2F0aW9ucywgZWNobz1UUlVFfQ0KbG9jYXRpb25zIDwtIHJlYWRfY3N2KCJsb2NhdGlvbnMuY3N2IikgJT4lDQogIG11dGF0ZShlc3RhZG8gICAgPSBybV9hY2NlbnQoc3RyX3RvX3VwcGVyKGVzdGFkbykpLCAjIGp1c3QgdG8gbWFrZSBzdXJlIA0KICAgICAgICAgbXVuaWNpcGlvID0gcm1fYWNjZW50KHN0cl90b191cHBlcihtdW5pY2lwaW8pKSwNCiAgICAgICAgIHBhcnJvcXVpYSA9IHJtX2FjY2VudChzdHJfdG9fdXBwZXIocGFycm9xdWlhKSksDQogICAgICAgICB1YmljYWNpb24gPSBybV9hY2NlbnQoc3RyX3RvX3VwcGVyKHViaWNhY2lvbikpKQ0KYGBgDQoNCj4gTWF5YmUgd2Ugc2hvdWxkIGFkZCBuZXcgcGNvZGVzIGZvciAidG9kbyBtdW5pY2lwaW8iIGFuZCAgInRvZG8gZXN0YWRvIjsgd2lsbCB0aGV5IGJlIGFidXNlZD8NCg0KYGBge3IsIGxvY2F0aW9ucy1jaGVjaywgZWNobz1UUlVFfQ0KIyBzZWUgaWYgeW91IG5lZWQgdG8gdXBkYXRlIGxvY2F0aW9ucyANCiMgbmV3IGxvY2F0aW9ucyBub3QgaW4gbG9jYXRpb25zLmNzdiB3aWxsIGJlIGNhdWdodCBieSB0aGUgYW50aS1qb2luKCkNCiBsb2NhdGlvbnNfYWRkIDwtIGFjdDEgJT4lIA0KICAgc2VsZWN0KGVzdGFkbywgcGNvZGUxLCBtdW5pY2lwaW8sIHBjb2RlMiwgcGFycm9xdWlhLCBwY29kZTMsIHViaWNhY2lvbiwNCiAgICAgICAgICBsYXRpdHVkLCBsb25naXR1ZCkgJT4lIA0KICAgZGlzdGluY3QoKSAlPiUgDQogICBhbnRpX2pvaW4obG9jYXRpb25zLCBieSA9ICJ1YmljYWNpb24iKQ0KYGBgDQoNCg0KIyMjIDNiLiBTcGxpdHRpbmcgdGhlIGRhdGFzZXQgaW50byBjbGVhbiBhbmQgZGlydHkNCg0KYGBge3Igc3BsaXQtY2xlYW4tZGlydHksIGVjaG89VFJVRX0NCiMgc3BsaXR0aW5nIGludG8gdHdvIGRhdGFzZXRzLCBvbmUgY2xlYW4gb25lIGRpcnR5LiANCmFkbV9kaXJ0eSA8LSBhY3QxICU+JSANCiAgZmlsdGVyKGlzLm5hKGVzdGFkbykgfCBpcy5uYShwY29kZTEpIHwNCiAgICAgICAgIGlzLm5hKG11bmljaXBpbykgfCBpcy5uYShwY29kZTIpIHwNCiAgICAgICAgIGlzLm5hKHBhcnJvcXVpYSkgfCBpcy5uYShwY29kZTMpKQ0KDQphZG1fY2xlYW4gPC0gYWN0MSAlPiUgDQogIGZpbHRlcighaXMubmEoZXN0YWRvKSAmICFpcy5uYShwY29kZTEpICYNCiAgICAgICAgICFpcy5uYShtdW5pY2lwaW8pICYgIWlzLm5hKHBjb2RlMikgJg0KICAgICAgICAgIWlzLm5hKHBhcnJvcXVpYSkgJiAhaXMubmEocGNvZGUzKSkgDQoNCmBgYA0KDQojIyMgM2MuIEZpbGwgaW4gbWlzc2luZyB2YWx1ZXMgd2l0aCBgY29hbGVzY2UoKWANCg0KPiBUaGUgbG9jYXRpb25zIHJlZmVyZW5jZSBkYXRhc2V0IGlzIHVzZWQgdG8gY2xlYW4gYGFkbV9kaXJ0eWAgYW5kIHJld3JpdGUgaXQuIFRoZSBgZGlzdGluY3QoKWAgY2FsbCBhdCB0aGUgZW5kIGlzIHRvIGVuc3VyZSB0aGF0IG5vIGR1cGxpY2F0ZXMgYXJlIGluY2x1ZGVkIGFzIHRoZSBgbGVmdF9qb2luKClgIGFyZ3VtZW50IHdpbGwgcHJvZHVjZSBkdXBsaWNhdGVzIChzdGlsbCBub3Qgc3VyZSBob3cgdG8gY29udHJvbCB0aGlzKS4gQWZ0ZXIgd2hpY2gsIGBhZG1fY2xlYW5gIGFuZCBgYWRtX2RpcnR5YCBhcmUgY29tYmluZWQgaW50byBgYWN0MmAuDQoNCmBgYHtyIGZpbGwgaW4gbWlzc2luZyB2YWx1ZXMsIGVjaG89VFJVRX0NCiMgZmlsbGluZyBpbiBtaXNzaW5nIHZhbHVlcw0KYWRtX2RpcnR5IDwtIGFkbV9kaXJ0eSAlPiUgDQogIGxlZnRfam9pbihsb2NhdGlvbnMsIGJ5ID0gInViaWNhY2lvbiIpICU+JSANCiAgbXV0YXRlKGVzdGFkbyAgICA9IGNvYWxlc2NlKGVzdGFkby54LCBlc3RhZG8ueSksDQogICAgICAgICBwY29kZTEgICAgPSBjb2FsZXNjZShwY29kZTEueCwgcGNvZGUxLnkpLA0KICAgICAgICAgbXVuaWNpcGlvID0gY29hbGVzY2UobXVuaWNpcGlvLngsIG11bmljaXBpby55KSwNCiAgICAgICAgIHBjb2RlMiAgICA9IGNvYWxlc2NlKHBjb2RlMi54LCBwY29kZTIueSksDQogICAgICAgICBwYXJyb3F1aWEgPSBjb2FsZXNjZShwYXJyb3F1aWEueCwgcGFycm9xdWlhLnkpLA0KICAgICAgICAgcGNvZGUzICAgID0gY29hbGVzY2UocGNvZGUzLngsIHBjb2RlMy55KSkgJT4lIA0KICBzZWxlY3QoLWVzdGFkby54LCAtZXN0YWRvLnksIC1wY29kZTEueCwgLXBjb2RlMS55LA0KICAgICAgICAgLW11bmljaXBpby54LCAtbXVuaWNpcGlvLnksIC1wY29kZTIueCwgLXBjb2RlMi55LA0KICAgICAgICAgLXBhcnJvcXVpYS54LCAtcGFycm9xdWlhLnksIC1wY29kZTMueCwgLXBjb2RlMy55KSAlPiUgDQogIGRpc3RpbmN0KCkgIyByZW1vdmluZyBkdXBsaWNhdGUgcm93cyBmcm9tIHRoZSBqb2luIA0KDQojIGJpbmRfcm93cygpIGRvZXMgbm90IGNhcmUgYWJvdXQgY29sdW1uIHNlcXVlbmNlIA0KIyBidXQgcHV0IGFkbV9jbGVhbiBmaXJzdCBzbyB0aGF0IHRoZSBvcmlnaW5hbCBvcmRlciBpcyBwcmVzZXJ2ZWQNCmFjdDIgPC0gYmluZF9yb3dzKGFkbV9jbGVhbiwgYWRtX2RpcnR5KQ0KDQpgYGANCg0KIyMjIDNkLiBFcnJvciBjaGVja2luZyB0aGUgam9pbg0KPiBwcmludGluZyB0b3RhbCBiZW5lZmljaWFyaWVzIGZvciBgYWN0MWAgYW5kIGBhY3QyYCwgZm9sbG93ZWQgYnkgYG5yb3coKWAgZm9yIGJvdGguIA0KDQpgYGB7ciBqb2luLWVycm9yLWNoZWNrfQ0KIyBlcnJvciBjaGVja2luZw0KcmJpbmQoc3VtKGFjdDEkdG90YWxfYmVuZWZpY2lhcmlvcywgbmEucm0gPSBUUlVFKSwNCiAgICAgIHN1bShhY3QyJHRvdGFsX2JlbmVmaWNpYXJpb3MsIG5hLnJtID0gVFJVRSksDQogICAgICBucm93KGFjdDEpLA0KICAgICAgbnJvdyhhY3QyKSkNCmBgYA0KDQombmJzcDsNCg0KIyMgNC4gQmVuZWZpY2lhcnkgZGlzYWdncmVnYXRpb24gDQo+IFRoaXMgaXMgdG8gY2hlY2sgdGhhdCBgdG90YWxfYmVuZWZpY2lhcmlvc2AgaXMgZXF1YWwgdG8gdGhlIHN1bSBvZiBhbGwgZGlzYWdncmVnYXRlZCBjb2x1bW5zLiBGaXJzdCwgd2UgbXV0YXRlIGEgbmV3IGNvbHVtbiBieSBzdW1taW5nIGFsbCB0aGUgZGlzYWdncmVnYXRlZCBiZW5lZmljaWFyaWVzIGFuZCBjYWxsaW5nIGl0IGB0b3RhbF9iZW5fY2hlY2tgLiBUaGVuLCB3ZSBtdXRhdGUgYSBuZXcgY29sdW1uIGluIHRociBkYXRhc2V0IGNhbGxlZCBgbm9fZXNwX2JlbmAgb3IgYmVuZWZpY2lhcmlvcyBubyBlc3BlY2lmaWNhZG9zIHNvIHRoYXQgd2UgbWFpbnRhaW4gdGhlIHVuLWRpc2FnZ3JlZ2F0ZWQgYmVuZWZpY2lhcmllcyB3aXRob3V0IHBvbGx1dGluZyB0aGUgcmVzdCBvZiB0aGUgZGF0YXNldC4NCg0KYGBge3IgYmVuY2hlY2stYW5kLW5vLWVzcC1iZW4sIGVjaG89VFJVRSB9DQojIG11dGF0aW5nIGJlbmNoZWNrIGFuZCB1bnNwZWNpZmllZCBiZW5lZmljaWFyaWVzIGNvbHVtbnMgDQphY3QyIDwtIGFjdDIgJT4lIA0KICBtdXRhdGUodG90YWxfYmVuX2NoZWNrID0gc2VsZWN0KC4sIG1fMF8zOm1fbWF5b3Jlc19kZV8xOSkgJT4lICByb3dTdW1zKG5hLnJtID0gVFJVRSksIA0KICAgICAgICAgbm9fZXNwX2JlbiAgICAgID0gcm91bmQodG90YWxfYmVuZWZpY2lhcmlvcykgLSByb3VuZCh0b3RhbF9iZW5fY2hlY2spKSANCg0KYGBgDQoNCj4gTmV4dCwgd2UgcHJpbnQgcm93cyB3aGVyZSB0aGUgc3VtIG9mIGRpc2FnZ3JlZ2F0ZWQgYmVuZWZpY2lhcmllcyAoYHRvdGFsX2Jlbl9jaGVja2ApIGRvIG5vdCBtYXRjaCB0aGUgdG90YWxzIHJlcG9ydGVkIGluIHRoZSBgdG90YWxfYmVuZWZpY2lhcmlvc2AgY29sdW1uIHNvIHRoYXQgd2UgY2FuIHJldHVybiB0byB0aGUgcmVsZXZhbnQgcGFydGllcyBmb3IgZm9sbG93IHVwLiANCg0KYGBge3IgcHJpbnRpbmctYmVuY2hlY2t9DQojIHByaW50aW5nIHRoZSBiZW5jaGVjaw0KIyB0aGUgcm91bmQgaXMgbmVjZXNzYXJ5IGR1ZSB0byBmbG9hdGluZyBwb2ludCBhcml0aG1ldGljIGFzIHNvbWUgdmFsdWVzIGFyZQ0KIyBjbG9zZSBlbm91Z2ggdG8gMCB0byBiZSBpZ25vcmVkIGJ5IHVzIGJ1dCBub3QgYnkgUi4gDQojIG9ubHkgcGFuZGVyKCkgaWYgeW91IHdhbnQgdG8gcmVhZCB0aGUgaHRtbA0Kbm9fZXNwIDwtIGFjdDIgJT4lIA0KICBmaWx0ZXIocm91bmQodG90YWxfYmVuZWZpY2lhcmlvcykgIT0gcm91bmQodG90YWxfYmVuX2NoZWNrKSkgJT4lIA0KICBzZWxlY3Qob3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCBhY3RpdmlkYWRfZGVzYywgDQogICAgICAgICB1YmljYWNpb24sIHRvdGFsX2Jlbl9jaGVjaywgdG90YWxfYmVuZWZpY2lhcmlvcywgbm9fZXNwX2JlbikNCg0Ka2FibGUobm9fZXNwLCBjYXB0aW9uID0gIlVuZGlzYWdncmVnYXRlZCBiZW5lZmljaWFyaWVzIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAiYm9yZGVyZWQiLCBmb250X3NpemUgPSAxMikNCmBgYA0KDQombmJzcDsNCg0KIyMgNS4gT3V0cHV0cw0KDQojIyMgNWEuIENsZWFuZWQgd2lkZSB2ZXJzaW9uDQpgYGB7ciBkYXRlc3RhbXAsIGVjaG89VFJVRX0NCiMgdGltZXN0YW1wIGZvciBhbGwgdGhlIGZpbGVzIHRvIGJlIHdyaXR0ZW4gYmVsb3cNCm5vdyA8LSBTeXMudGltZSgpDQpgYGANCg0KPiBGb3Igc3VibWlzc2lvbnMgdG8gT0NIQSwgdGhpcyBvbmUgYWxpZ25zIHdpdGggdGhlaXIgZm9ybWF0DQoNCmBgYHtyIGNsZWFuZWQtd2lkZSwgZWNobz1UUlVFLCBldmFsPUZBTFNFfQ0KIyB0dXJuIG9uIGV2YWwgaWYgeW91IHdhbnQgdGhlIGZpbGUNCmZpbGVuYW1lX3dpZGUgPC0gcGFzdGUwKGZvcm1hdChub3csICIleSVtJWRfJUglTV8iKSwgIjVXX3dpZGUuY3N2IikNCndyaXRlX2NzdihhY3QyLCBmaWxlbmFtZV93aWRlKQ0KYGBgDQoNCiMjIyA1Yi4gVW5pcXVlIGJlbmVmaWNpYXJpZXMNCg0KPiBUaGlzIHNlY3Rpb24gcGl2b3RzIHRoZSBkYXRhc2V0IGxvbmdlciBpbnRvIHRpZHkgZGF0YSwgd2l0aCBvbmUgb2JzZXJ2YXRpb24gcGVyIGluc3RhbmNlIG9mIGFnZSBhbmQgc2V4OyB0aGlzIGlzIG5lY2Vzc2FyeSBmb3IgZWFzeSBwbG90dGluZyBhbmQgYW5hbHlzaXMuIEFkZGl0aW9uYWxseSwgcm93cyB3aXRoIG5vIGJlbmVmaWNpYXJpZXMgYXJlIGZpbHRlcmVkIG91dC4gDQoNCj4gVGhlIGRhdGFzZXQgYHVfYmVuYCBpcyBjcmVhdGVkIGJ5IHRha2luZyB0aGUgaGlnaGVzdCBudW1iZXIgb2YgYmVuZWZpY2lhcmllcyBieSBhZ2UgYW5kIHNleCBncm91cCBieSBsb2NhdGlvbiBvZiBhbGwgbm9uLXJlY3VycmVudCBiZW5lZmljaWFyaWVzLiBUaGUgY29sdW1ucyBhcmUgdGhlbiBmaWx0ZXJlZCBkb3duIHRvIGNyZWF0ZSBhIG1vcmUgdXNhYmxlIGRhdGFzZXQuIFdlIHdpbGwgdXNlIHRoaXMgZGF0YXNldCBmb3IgYW55IG9wZXJhdGlvbnMgcmVsYXRlZCB0byB1bmlxdWUgYmVuZWZpY2lhcmllcyAoaW5kaXZpZHVhbHMpLCBpbmNsdWRpbmcgY29tcGFyaXNvbnMgd2l0aCBjZW5zdXMgZGF0YSB0byBkZXRlcm1pbmUgcmVhY2ggYW5kIGNvdmVyYWdlIGFzIHdlbGwgYXMgZ2VvZ3JhcGhpYyBhbmFseXNpcy4gV2UgZHJvcCBhY3Rpdml0eSBpbmZvcm1hdGlvbiBmcm9tIHRoaXMgZGF0YXNldCBhcyBpdCBvbmx5IGNvbnRhaW5zIHRoZSBtYXggb2YgcGVyIGRpc2FnZ3JlZ2F0aW9uIGdyb3VwIHBlciBsb2NhdGlvbiBhbnl3YXkuIA0KDQpgYGB7ciB1bmlxdWUtYmVuZmljaWFyaWVzLCBlY2hvPVRSVUV9DQojIHBpdm90aW5nIGxvbmdlciBhbmQgY3JlYXRpbmcgbmV3IGRhdGFmcmFtZQ0KdV9iZW4gPC0gYWN0MiAlPiUgDQogIHNlbGVjdCgtdF9mX2JlbiwgLXRvdGFsX2Jlbl9jaGVjaykgJT4lICMgcmVtZW1iZXIgdG8gZHJvcCB0aGVtDQogIHJlbG9jYXRlKG1lc19zb2xvKSAlPiUgIyBtb3ZlcyBtZXNfc29sbyB0byB0aGUgZmlyc3QgdmFyaWFibGUNCiAgcGl2b3RfbG9uZ2VyKG1fMF8zOm5vX2VzcF9iZW4sIA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZGVzYWdyZWdhY2lvbiIsIHZhbHVlc190byA9ICJiZW5lZmljaWFyaW9zIikgJT4lIA0KICBmaWx0ZXIocmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zID09IEZBTFNFKSAlPiUNCiAgZmlsdGVyKGJlbmVmaWNpYXJpb3MgIT0gMCkgJT4lICMgZW1wdHkgY2VsbHMgYXJlIDAgaW4gdGhlIDVXIHRhYmxlDQogIGdyb3VwX2J5KHViaWNhY2lvbiwgZGVzYWdyZWdhY2lvbikgJT4lIA0KICBzbGljZSh3aGljaC5tYXgoYmVuZWZpY2lhcmlvcykpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KG1lc19zb2xvLCBlc3RhZG8sIHBjb2RlMSwgbXVuaWNpcGlvLCBwY29kZTIscGFycm9xdWlhLCBwY29kZTMsIA0KICAgICAgICAgdWJpY2FjaW9uLCBsYXRpdHVkLCBsb25naXR1ZCwNCiAgICAgICAgIGRlc2FncmVnYWNpb24sIGJlbmVmaWNpYXJpb3MpDQpgYGANCg0KYGBge3Igd3JpdGluZy11LWJlbi1jc3YsIGVjaG89VFJVRSwgZXZhbD1GQUxTRX0NCiMgd3JpdGluZyBjc3Ygb2YgdV9iZW4gd2l0aCBkYXRlc3RhbXANCiMgdHVybiBvbiBldmFsIGlmIHlvdSB3YW50IHRoZSBmaWxlIA0KZmlsZW5hbWVfdV9iZW4gPC0gcGFzdGUwKGZvcm1hdChub3csICIleSVtJWRfJUglTV8iKSwgInVfYmVuLmNzdiIpDQp3cml0ZV9jc3YodV9iZW4sIGZpbGVuYW1lX3VfYmVuKQ0KYGBgDQoNCg0KIyMjIDVjLiBCZW5lZmljaWFyaWVzIGJ5IGFjdGl2aXR5DQoNCj4gVGhlIGRhdGFzZXQgYGFjdF9iZW5gIGlzIGZvciBhY3Rpdml0eS13aXNlIGFuYWx5c2lzLiBPbmx5IHRoZSByb3dzIG1hcmtlZCBhcyBgcmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zID09IEZBTFNFYCBoYXZlIGJlZW4gc2VsZWN0ZWQuIFRoZSBmaXJzdCBpbnN0YW5jZSBvZiByZWN1cnJpbmcgYmVuZWZpY2lhaXJlcyBpcyBtYXJrZWQgRkFMU0UsIHdpdGggYWxsIHN1YnNlcXVlbnQgZW50cmllcyBiZWluZyBtYXJrZWQgVFJVRS4gU2ltaWxhciB0byBgdV9iZW5gLCBpdCBoYXMgYWxzbyBiZWVuIHBpdm90ZWQgbG9uZ2VyIGludG8gdGlkeSBkYXRhLiANCg0KPiBQbGVhc2Ugbm90IHRoYXQgdGhlcmUgaXMgZG91YmxlIGNvdW50aW5nIGluIHRoaXMgZGF0YXNldCBhcyBzcGVjaWZpYyBiZW5lZmljaWFyaWVzIG1pZ2h0IGJlZW4gcmVhY2hlZCBieSBtb3JlIHRoYW4gb25lIGFjdGl2aXR5LiBGb3IgZ2VvZ3JhcGhpYyBhbmFseXNpcywgcGxlYXNlIHVzZSBgdV9iZW5gLg0KDQpgYGB7ciBiZW5lZmljaWFyaWVzLWJ5LWFjdGl2aXR5LCBlY2hvPVRSVUV9DQojIFRoaXMgaXMgdGhlIGRhdGFzZXQgZm9yIGJlbmVmaWNpYXJpZXMNCmFjdF9iZW4gPC0gYWN0MiAlPiUNCiAgc2VsZWN0KC10X2ZfYmVuLCAtdG90YWxfYmVuX2NoZWNrKSAlPiUgIyByZW1lbWJlciB0byBkcm9wIHRoZW0NCiAgcmVsb2NhdGUobWVzX3NvbG8pICU+JSAjIG1vdmVzIG1lc19zb2xvIHRvIHRoZSBmaXJzdCB2YXJpYWJsZQ0KICBmaWx0ZXIocmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zID09IEZBTFNFKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKG1fMF8zOm5vX2VzcF9iZW4sIA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZGVzYWdyZWdhY2lvbiIsIHZhbHVlc190byA9ICJiZW5lZmljaWFyaW9zIikgJT4lIA0KICBmaWx0ZXIoYmVuZWZpY2lhcmlvcyAhPSAwKSAlPiUgIyBlbXB0eSBjZWxscyBhcmUgMCBpbiB0aGUgNVcgdGFibGUNCiAgZ3JvdXBfYnkodWJpY2FjaW9uLCBkZXNhZ3JlZ2FjaW9uKSAlPiUgDQogIHNlbGVjdChtZXNfc29sbywgbm9tYnJlX2RlbF9wcm95ZWN0bywgb3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCANCiAgICAgICAgIGVzdGFkbywgcGNvZGUxLCBtdW5pY2lwaW8sIHBjb2RlMiwgcGFycm9xdWlhLCBwY29kZTMsIA0KICAgICAgICAgdWJpY2FjaW9uLCBsYXRpdHVkLCBsb25naXR1ZCwNCiAgICAgICAgIGFjdGl2aWRhZF9jb2RpZ28sIGFjdGl2aWRhZF9kZXNjLCBhY3RfY292aWQsDQogICAgICAgICBkZXNhZ3JlZ2FjaW9uLCBiZW5lZmljaWFyaW9zKQ0KDQpgYGANCg0KDQpgYGB7ciB3cml0aW5nLWFjdC1iZW4tY3N2LCBlY2hvPVRSVUUsIGV2YWw9RkFMU0V9DQojIHdyaXRpbmcgY3N2IGFjdF9iZW4gd2l0aCBkYXRlc3RhbXANCiMgdHVybiBvbiBldmFsIGlmIHlvdSB3YW50IHRoZSBmaWxlIA0KZmlsZW5hbWVfYWN0X2JlbiA8LSBwYXN0ZTAoZm9ybWF0KG5vdywgIiV5JW0lZF8lSCVNXyIpLCAiYWN0X2Jlbi5jc3YiKQ0Kd3JpdGVfY3N2KGFjdF9iZW4sIGZpbGVuYW1lX2FjdF9iZW4pDQpgYGANCg0KIyMjIDVkLiBDb21wYXJpbmcgYHVfYmVuYCwgYGFjdF9iZW5gIGFuZCBkaWZmZXJlbmNlDQoNCj4gUGxlYXNlIG5vdGUgdGhhdCB0aGlzIHN0aWxsIGhhcyB0aGF0IHJhZGlvIG1lc3NhZ2luZyBhY3Rpdml0eSBsdW1wZWQgaW4gd2l0aCB0aGUgdG90YWxzLiANCg0KYGBge3IgY29tcGFyaW5nfQ0KDQpyYmluZChzdW0odV9iZW4kYmVuZWZpY2lhcmlvcyksDQogICAgICBzdW0oYWN0X2JlbiRiZW5lZmljaWFyaW9zKSwNCiAgICAgIHN1bSh1X2JlbiRiZW5lZmljaWFyaW9zKSAtIHN1bShhY3RfYmVuJGJlbmVmaWNpYXJpb3MpKQ0KYGBgDQoNCiZuYnNwOw0KDQojIEIuIFJlcG9ydGluZyBvbiB0aGUgNVcgZGF0YSANCg0KYGBge3IgcmVwb3J0LXNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyByZWFkIGluIGNlbnN1cyByZWZlcmVuY2UgZGF0YXNldA0KY2VuX3JlZiA8LSByZWFkX2V4Y2VsKCJjZW5zdXNfZGF0YV8yMDE5MTEyMi54bHN4Iiwgc2hlZXQgPSAiZGF0YSIpICU+JSANCiAgY2xlYW5fbmFtZXMoKSAlPiUNCiAgc2VsZWN0KGVzdGFkbywgcGNvZGUxLCBtdW5pY2lwaW8sIHBjb2RlMiwgcGFycm9xdWlhLCBwY29kZTMsIGZpZWxkX29mZmljZSwNCiAgICAgICAgIHBvYmxhY2lvbl90b3RhbF8yMDExLCB4XzIwMTlfcG9ibGFjaW9uX3BhcnJvcXVpYWxfdG90YWwsDQogICAgICAgICBoYW1fMjAxOV9hbWJpdG9zX2dlLCBoYW1fMjAxOV94eF9wb2JyZXphX2Vudl9wb3JfcGFycm9xdWlhLCANCiAgICAgICAgIGhhbV8yMDE5X3h4X3BvYmxhY2lvbl9wb2JyZV9wb3JfcGFycm9xdWlhLA0KICAgICAgICAgcG9ibGFjaW9uX2luZmFudGlsX21lbm9yX2RlXzEyX2Fub3MsIHBvYmxhY2lvbl9hZG9sZXNjZW50ZXNfZGVfMTJfYV8xN19hbm9zLA0KICAgICAgICAgcG9ibGFjaW9uX2RlXzE4X2Fub3NfeV9tYXMsIA0KICAgICAgICAgcG9ibGFjaW9uX3VyYmFuYV9wZXJjZW50LCBhcmVhX2ttMiwgZGVuc2lkYWRfcG9ibGFjaW9uYWxfcHBsX2ttMiwNCiAgICAgICAgIG1hdHJpY3VsYV8yMDE3X2VkdWNhY2lvbl9pbmljaWFsLCBtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fcHJpbWFyaWEsIA0KICAgICAgICAgbWF0cmljdWxhXzIwMTdfZWR1Y2FjaW9uX21lZGlhKQ0KDQojIGZpbHRlcmluZyBvdXQgUFJPTU9DSU9OIE1FTlNBSkVTIENMQVZFUyBQQVJBIExBIENPTVVOSURBRCBFU0NPTEFSDQpDQTEwNSA8LSBhY3RfYmVuICU+JSBmaWx0ZXIoYWN0aXZpZGFkX2NvZGlnbyA9PSAiQ0ExLjA1IikNCg0KIyBjcmVhdGluZyBkYXRhc2V0cyB3aXRob3V0IENBMS4wNSBhbmQNCiMgZm9yIGFjdF9iZW4sIHJlY29kaW5nIFVOSUNFRiBhbmQgbXV0YXRpbmcgc2hvcnQgYWN0aXZpdHkgZGVzY3JpcHRpb25zDQphY3RfYmVuMiA8LSBhY3RfYmVuICU+JSANCiAgZmlsdGVyKGFjdGl2aWRhZF9jb2RpZ28gIT0gIkNBMS4wNSIpICU+JSANCiAgbXV0YXRlKG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSA9IA0KICAgICAgICAgICBzdHJfcmVwbGFjZV9hbGwob3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJVTklDRUYgLSBGb25kbyBkZSBsYXMgTmFjaW9uZXMgVW5pZGFzIHBhcmEgbGEgSW5mYW5jaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVOSUNFRiIpKSAlPiUgDQogIG11dGF0ZShhY3RpdmlkYWRfc2hvcnQgPSByZWNvZGUoYWN0aXZpZGFkX2NvZGlnbywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBMS4wMSA9ICIxLjAxX3JlaW5zZXJjaW9uIGVkdWNhdGl2YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBMS4wMiA9ICIxLjAyX25pdmVsYWNpb24geSBjYXBhY2l0YWNpb24iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQTEuMDMgPSAiMS4wM19raXRzIGVzY29sYXJlcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBMS4wNCA9ICIxLjA0X2FsaW1lbnRhY2lvbiBlc2NvbGFyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ExLjA1ID0gIjEuMDVfcHJvbW9jaW9uIG1lbnNhamVzIGNsYXZlcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBMS4wNiA9ICIxLjA2X2Fwb3lvIHBzaWNvZWR1Y2F0aXZvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ExLjA3ID0gIjEuMDdfYWN0aXZpZGFkZXMgcmVjcmVhdGl2YXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQTIuMDggPSAiMi4wOF9lZHVjYWNpb24gYSBkaXN0YW5jaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQTIuMDkgPSAiMi4wOV9mb3JtYWNpb24gZG9jZW50ZXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQTIuMTAgPSAiMi4xMF9iZWNhcyBkb2NlbnRlcyIpKQ0KICAgICAgICAgICAgICAgICAgICANCnVfYmVuMiA8LSB1X2JlbiAlPiUgZmlsdGVyKCFzdHJfZGV0ZWN0KC4kdWJpY2FjaW9uLCAiXlJBRElPIikpDQpgYGANCg0KJm5ic3A7DQoNCj4gVGhpcyBpcyBhbiBlbnRpcmVseSBhdXRvbWF0ZWQgcmVwb3J0IC0tIGFsbCBjaGFydHMgYW5kIHRhYmxlcywgYXMgd2VsbCBhcyBhbGwgZmlndXJlcyB3aXRoaW4gdGhlIHJlcG9ydCBoYXZlIGJlZW4gZ2VuZXJhdGVkIGZyb20gdGhlIGRhdGEsIHdpdGggbm8gbWFudWFsIGlucHV0LiBUaGlzIHJlcG9ydCBtYWtlcyB1c2Ugb2YgdGhlIG91dHB1dHMgb2YgdGhlIGA1V19jbGVhbmluZ2Agc2VjdGlvbiBhYm92ZS4gVGhpcyBzZXQgb2YgNVcgZGF0YSBwZXJ0YWlucyB0byB0aGUgRWR1Y2F0aW9uIENsdXN0ZXIgaW4gVmVuZXp1ZWxhIGFuZCBoYXMgaGFkIHBhcnRuZXIgaW5mb3JtYXRpb24gcmVtb3ZlZC4gQ29kZSB3aWxsIG5vdCBiZSBzaG93biBpbiB0aGlzIHNlY3Rpb24gLS0geW91IGNhbiBkb3dubG9hZCB0aGUgUm1kIGF0IHRoZSB0b3AtbGVmdCBjb3JuZXIgb2YgdGhpcyBkb3VjdW1lbnQuICANCg0KJm5ic3A7DQoNCiMjIDEuIFN1bW1hcnkgb2YgYmVuZWZpY2lhcmllcyBieSBhY3Rpdml0eSwgd2l0aCBzZXggcmF0aW8NCg0KYGBge3Igc3VtbWFyeS1UQUJMRS1hY3Rpdml0eS1hbmQtc2V4fQ0KDQojIGFzIGEgbm90ZSwgaSBkb24ndCB0aGluayB5b3UgY2FuIHB1dCBhbiBzdHJfZGV0ZWN0IGluc2lkZSBhIHN1bW1hcmlzZQ0KYWN0X2JlbjIgJT4lIA0KICBtdXRhdGUoc2V4X2JlbiA9IGlmZWxzZShzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sICJebSIpLCAibWFsZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sICJeZiIpLCAiZmVtYWxlIiwgIm5vX2VzcCIpKSkgJT4lIA0KICBtdXRhdGUoYWN0aXZpZGFkID0gYWN0aXZpZGFkX2Rlc2MpICU+JSANCiAgZ3JvdXBfYnkoYWN0aXZpZGFkKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbCA9IHN1bShiZW5lZmljaWFyaW9zLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgbWFsZSA9IHN1bSgoYmVuZWZpY2lhcmlvc1tzZXhfYmVuID09ICJtYWxlIl0pKSwNCiAgICAgICAgICAgIGZlbWFsZSA9IHN1bSgoYmVuZWZpY2lhcmlvc1tzZXhfYmVuID09ICJmZW1hbGUiXSkpLA0KICAgICAgICAgICAgc2V4X3JhdGlvID0gcm91bmQoKG1hbGUvZmVtYWxlKSwgZGlnaXRzID0gMikpICU+JSANCiAgbXV0YXRlKHBlcmNlbnRfb2ZfdG90YWwgPSByb3VuZCgodG90YWwgLyBzdW0odG90YWwpICogMTAwKSwgZGlnaXRzID0gMikpICU+JSANCiAgcmVsb2NhdGUocGVyY2VudF9vZl90b3RhbCwgLmFmdGVyID0gdG90YWwpICU+JSANCiAgYXJyYW5nZShkZXNjKHRvdGFsKSkgJT4lIA0KICBwYW5kZXIoYmlnLm1hcmsgPSAiLCIsIHN0eWxlID0gInJtYXJrZG93biIpDQoNCmBgYA0KDQo+IEEgdG90YWwgb2YgX19gciBmb3JtYXQocm91bmQoc3VtKHVfYmVuMiRiZW5lZmljaWFyaW9zKSksIGJpZy5tYXJrID0gIiwiKWBfXyBpbmRpdmlkdWFscyBoYXZlIGJlZW4gcmVhY2hlZCB0byBkYXRlLiBJbiB0ZXJtcyBvZiBmcmVxdWVuY2llcyAoaW5jbHVzaXZlIG9mIGRvdWJsZSBjb3VudGluZyksIF9fYHIgZm9ybWF0KHN1bShhY3RfYmVuMiRiZW5lZmljaWFyaW9zKSwgYmlnLm1hcmsgPSAiLCIpYF9fIGhhdmUgYmVlbiByZWFjaGVkLiANCg0KPiBBZGRpdGlvbmFsbHksIHRoZSBfX2ByIGZvcm1hdChzdW0oQ0ExMDUkYmVuZWZpY2lhcmlvcyksIGJpZy5tYXJrID0gIiwiKWBfXyBiZW5lZmljaWFyeSBmcmVxdWVuY2llcyByZWFjaGVkIGJ5IHRoZSBhY3Rpdml0eSBQUk9NT0NJT04gTUVOU0FKRVMgQ0xBVkVTIFBBUkEgTEEgQ09NVU5JREFEIEVTQ09MQVIgaGF2ZSBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgdG90YWxzIGluIHRoaXMgcmVwb3J0IGFzIHRoZSBhY3Rpdml0eSBjb25zaXN0cyBvZiBzb2xlbHkgcmFkaW8gbWVzc2FnaW5nLiANCg0KJm5ic3A7DQoNCiMjIDIuIEJlbmVmaWNpYXJpZXMgYnkgYWdlIGdyb3VwDQoqZmlndXJlcyBhcmUgdW5pcXVlIGJlbmVmaWNpYXJpZXMvaW5kaXZpZHVhbHMqDQoNCmBgYHtyIFBMT1QtYmVuZWZpY2lhcmllcy1ieS1hZ2V9DQojIHRvIHJlb3JkZXIgdGhlIHBsb3QNCm9yZHZlYyA8LSBjKCIwLTMiLCAiMy02IiwgIjctMTIiLCAiMTItMTciLCAiMTgtMTkiLCAibWF5b3JfcXVlXzE5IikNCg0KIyBkZiBmb3IgdGhlIHBsb3QNCmFnZV91X2JlbiA8LSB1X2JlbjIgJT4lICMgaW1wb3J0YW50IHRvIHVzZSB1X2JlbiBoZXJlIA0KICBtdXRhdGUoYWdlX2JlbiA9IGNhc2Vfd2hlbigNCiAgICBzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sIjBfMyQiKSB+ICIwLTMiLA0KICAgIHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwiM182JCIpIH4gIjMtNiIsDQogICAgc3RyX2RldGVjdChkZXNhZ3JlZ2FjaW9uLCAiN18xMiQiKSB+ICI3LTEyIiwgDQogICAgc3RyX2RldGVjdChkZXNhZ3JlZ2FjaW9uLCAiMTJfMTckIikgfiAiMTItMTciLA0KICAgIHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwgIjE4XzE5JCIpIH4gIjE4LTE5IiwNCiAgICBzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sICJtYXlvcmVzX2RlXzE5JCIpIH4gIm1heW9yX3F1ZV8xOSIsIA0KICAgIFRSVUUgfiAibm9fZXNwIikpICU+JQ0KICBmaWx0ZXIoYWdlX2JlbiAhPSAibm9fZXNwIikgJT4lIA0KICBncm91cF9ieShhZ2VfYmVuKSAlPiUgDQogIHN1bW1hcmlzZShiZW5lZmljaWFyaW9zID0gc3VtKGJlbmVmaWNpYXJpb3MpKQ0KDQpnZ3Bsb3QoZGF0YSA9IGFnZV91X2JlbiwgYWVzKHggPSBmY3RfcmVvcmRlcihhZ2VfYmVuLCBvcmR2ZWMpLCB5ID0gYmVuZWZpY2lhcmlvcykpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICJjb3JuZmxvd2VyYmx1ZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6Y29tbWEoYmVuZWZpY2lhcmlvcykpLCB2anVzdCA9IC0wLjI1LCBzaXplID0gNCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gdW5pdF9mb3JtYXQodW5pdCA9ICJLIiwgc2NhbGUgPSAxZS0zLCBzZXAgPSAiIikpICsNCiAgeGxhYigiR3J1cG9zIHBvciBFZGFkIikgKyB5bGFiKCJCZW5lZmljaWFyaW9zIikgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkNCg0KYGBgDQoNCiZuYnNwOw0KDQojIyMgMmEuIEJlbmVmaWNpYXJpZXMgYnkgYWdlIGNvbXBhcmVkIHRvIDIwMTcgRW5yb2xsbWVudA0KDQpgYGB7ciBSRUYtbWF0cmljLWJlbn0NCiMgcmVmZXJlbmNlIGRmIGZvciB0aGUgdGFibGUgYW5kIHRleHQgYmVsb3csIHJlc3RydWN0dXJpbmcgZW5yb2xsbWVudCBkYXRhIGZyb20gY2VuX3JlZg0KbWF0cmljX2JlbiA8LSBjZW5fcmVmICU+JSANCiAgc2VsZWN0KG1hdHJpY3VsYV8yMDE3X2VkdWNhY2lvbl9pbmljaWFsLCBtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fcHJpbWFyaWEsIA0KICAgICAgICAgbWF0cmljdWxhXzIwMTdfZWR1Y2FjaW9uX21lZGlhKSAlPiUNCiAgcmVuYW1lKCIzLTYiID0gbWF0cmljdWxhXzIwMTdfZWR1Y2FjaW9uX2luaWNpYWwsDQogICAgICAgICAiNy0xMiIgPSBtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fcHJpbWFyaWEsDQogICAgICAgICAiMTItMTciID0gbWF0cmljdWxhXzIwMTdfZWR1Y2FjaW9uX21lZGlhKSAlPiUgDQogIHBpdm90X2xvbmdlcihldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gImFnZV9iZW4iLCB2YWx1ZXNfdG8gPSAibWF0cmljdWxhMjAxNyIsIA0KICAgICAgICAgICAgICAgdmFsdWVzX2Ryb3BfbmEgPSBUUlVFKSAlPiUgDQogIGdyb3VwX2J5KGFnZV9iZW4pICU+JSANCiAgc3VtbWFyaXNlKG1hdHJpY3VsYTIwMTcgPSBzdW0obWF0cmljdWxhMjAxNykpICU+JQ0KICBsZWZ0X2pvaW4oYWdlX3VfYmVuKSAlPiUgDQogIG11dGF0ZShwZXJjZW50X3RvdGFsID0gYmVuZWZpY2lhcmlvcy9tYXRyaWN1bGEyMDE3ICogMTAwKSAlPiUgDQogIHJlbG9jYXRlKGJlbmVmaWNpYXJpb3MsIC5hZnRlciA9IGFnZV9iZW4pICU+JSANCiAgcmVuYW1lKGBFZGFkIGdydXBvYCA9IGFnZV9iZW4pICU+JSANCiAgc2xpY2UoMiwzLDEpICAjIHJlYXJyYW5naW5nIHJvd3MNCiAgDQpgYGANCg0KPiBXaXRoIHJlZmVyZW5jZSB0byB0aGUgMjAxNyBNYXRyaWN1bGEgZGF0YXNldCwgd2UgY2FuIHNlZSB0aGF0IHRoZSBFZHVjYXRpb24gcHJvZ3JhbW1lIGhhcyByZWFjaGVkIGFuIG92ZXJhbGwgYXZlcmFnZSBvZiBfX2ByIHJvdW5kKHN1bShtYXRyaWNfYmVuJGJlbmVmaWNpYXJpb3MpLyhzdW0obWF0cmljX2JlbiRtYXRyaWN1bGEyMDE3KSkqMTAwKWAlX18gb2Ygc2Nob29sZ29pbmcgY2hpbGRyZW4gYWdlZCAzLTE3IG5hdGlvbndpZGUuIENoaWxkcmVuIGFnZWQgMy0xNyBjb25zaXR1dGUgX19gciByb3VuZChzdW0obWF0cmljX2JlbiRiZW5lZmljaWFyaW9zKS8oc3VtKHVfYmVuMiRiZW5lZmljaWFyaW9zKSkqMTAwKWAlX18gb2YgYWxsIFVOSUNFRiBiZW5lZmljaWFyaWVzLiANCg0KYGBge3IgVEFCTEUtbWF0cmljLWJlbn0NCnBhbmRlcihtYXRyaWNfYmVuLCBiaWcubWFyayA9ICIsIiwgc3R5bGUgPSAicm1hcmtkb3duIikNCmBgYA0KDQombmJzcDsNCg0KIyMgMy4gQ2hhbmdlcyBzaW5jZSBwcmV2aW91cyBtb250aA0KDQpgYGB7ciBSRUYtZm9yLXRleHQtY3VtdWxhdGl2ZS1kYXRhc2V0c30NCg0KIyBjcmVhdGluZyByZWZlcmVuY2UgZGZzIGZvciB0aGUgdGV4dCBhbmQgcGxvdCBiZWxvdw0KY3VtX3VfYmVuIDwtIHVfYmVuMiAlPiUgDQogIG11dGF0ZShtZXNfc29sbyA9IGFzLkRhdGUobWVzX3NvbG8pKSAlPiUgDQogIGFycmFuZ2UobWVzX3NvbG8pICU+JSANCiAgZ3JvdXBfYnkobWVzX3NvbG8pICU+JSANCiAgc3VtbWFyaXNlKHN1bV9iZW4gPSBzdW0oYmVuZWZpY2lhcmlvcykpICU+JSANCiAgbXV0YXRlKGN1bXVsYXRpdmUgPSBjdW1zdW0oc3VtX2JlbikpDQoNCmN1bV9hY3RfYmVuIDwtIGFjdF9iZW4yICU+JSANCiAgbXV0YXRlKG1lc19zb2xvID0gYXMuRGF0ZShtZXNfc29sbykpICU+JSANCiAgYXJyYW5nZShtZXNfc29sbykgJT4lIA0KICBncm91cF9ieShtZXNfc29sbykgJT4lIA0KICBzdW1tYXJpc2Uoc3VtX2JlbiA9IHN1bShiZW5lZmljaWFyaW9zKSkgJT4lIA0KICBtdXRhdGUoY3VtdWxhdGl2ZSA9IGN1bXN1bShzdW1fYmVuKSkNCmBgYA0KDQo+IFRoZSBudW1iZXIgb2YgaW5kaXZpZHVhbHMgcmVhY2hlZCBoYXMgaW5jcmVhc2VkIGJ5IF9fYHIgZm9ybWF0KGN1bV91X2JlblsxMSwzXSAtIGN1bV91X2JlblsxMCwzXSwgYmlnLm1hcmsgPSAiLCIpYF9fIGluIHRoZSBwYXN0IG1vbnRoLCByZWFjaGluZyBhIHRvdGFsIG9mIF9fYHIgZm9ybWF0KHJvdW5kKHN1bSh1X2JlbjIkYmVuZWZpY2lhcmlvcykpLCBiaWcubWFyayA9ICIsIilgX18uIFRoZSBudW1iZXIgb2YgYmVuZWZpY2lhcnkgZnJlcXVlbmNpZXMgcmVhY2hlZCBoYXMgaW5jcmVhc2VkIGJ5IF9fYHIgZm9ybWF0KGN1bV9hY3RfYmVuWzExLDNdIC0gY3VtX2FjdF9iZW5bMTAsM10sIGJpZy5tYXJrID0gIiwiKWBfXyBpbiB0aGUgc2FtZSBwZXJpb2QsIHJlYWNoaW5nIGEgdG90YWwgb2YgX19gciBmb3JtYXQoc3VtKGN1bV9hY3RfYmVuWzExLDNdKSwgYmlnLm1hcmsgPSAiLCIpYF9fLg0KDQpgYGB7ciAgbGluZS1QTE9ULWN1bXVsYXRpdmUtYmVuZWZpY2lhcmllc30NCnVfYmVuMiAlPiUgDQogIG11dGF0ZShtZXNfc29sbyA9IGFzLkRhdGUobWVzX3NvbG8pKSAlPiUgDQogIGFycmFuZ2UobWVzX3NvbG8pICU+JSANCiAgZ3JvdXBfYnkobWVzX3NvbG8pICU+JSANCiAgc3VtbWFyaXNlKHN1bV9iZW4gPSBzdW0oYmVuZWZpY2lhcmlvcykpICU+JSANCiAgbXV0YXRlKGN1bXVsYXRpdmUgPSBjdW1zdW0oc3VtX2JlbikpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVzX3NvbG8sIHkgPSBjdW11bGF0aXZlKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OmNvbW1hKGN1bXVsYXRpdmUpKSwgdmp1c3QgPSAtMC4yNSwgaGp1c3QgPSAxLCBzaXplID0gMykgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJWItJVkiLCBkYXRlX2JyZWFrcyA9ICIxIG1vbnRoIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjp1bml0X2Zvcm1hdCh1bml0ID0gIksiLCBzY2FsZSA9IDFlLTMsIHNlcCA9ICIiKSwNCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgwLDk1MDAwMCwgYnkgPSAyMDAwMDApKSArICMgd2hhdCBpcyB0aGlzIGJyZWFrcyBkb2luZz8NCiAgeGxhYigiTWVzIFJlcG9ydGFkbyIpICsgeWxhYigiQmVuZWZpY2lhcmlvcyAoY3VtdWxhdGl2bykiKQ0KYGBgDQoNCiZuYnNwOw0KDQojIyMgM2EuIFByb2dyZXNzIGJ5IGFjdGl2aXR5IGJ5IG1vbnRoDQoqbW91c2Ugb3ZlciB0byBzZWUgZGV0YWlscyoNCg0KDQpgYGB7ciBsaW5lLVBMT1RMWS1wcm9ncmVzcy1ieS1hY3Rpdml0eSwgZmlnLndpZHRoPTl9DQphY3RfbGluZXMgPC0gYWN0X2JlbjIgJT4lIA0KICBtdXRhdGUobWVzX3NvbG8gPSBhcy5EYXRlKG1lc19zb2xvKSkgJT4lIA0KICBncm91cF9ieShhY3RpdmlkYWRfc2hvcnQsIG1lc19zb2xvKSAlPiUgDQogIHN1bW1hcmlzZShjdW11bGF0aXZlID0gc3VtKGJlbmVmaWNpYXJpb3MpKSAlPiUgDQogIG11dGF0ZShjdW11bGF0aXZlID0gcm91bmQoY3Vtc3VtKGN1bXVsYXRpdmUpKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZXNfc29sbywgeSA9IGN1bXVsYXRpdmUsIGNvbG91ciA9IGFjdGl2aWRhZF9zaG9ydCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAwLjcpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiViLSVZIiwgZGF0ZV9icmVha3MgPSAiMSBtb250aCIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHVuaXRfZm9ybWF0KHVuaXQgPSAiSyIsIHNjYWxlID0gMWUtMywgc2VwID0gIiIpLCANCiAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9IGMoMCwgNTAwMDAwKSkgKw0KICB4bGFiKCIiKSArIHlsYWIoIkJlbmVmaWNpYXJpb3MiKSArDQogIHNjYWxlX2NvbG91cl9kaXNjcmV0ZShuYW1lID0gIkFjdGl2aWRhZCIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSkgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMiwgYnlyb3cgPSBUUlVFKSkNCg0KZ2dwbG90bHkoYWN0X2xpbmVzLCB0b29sdGlwID0gYygieCIsICJ5IiwgImNvbG91ciIpKSAlPiUgDQogIGxheW91dChzaG93bGVnZW5kID0gVFJVRSwgbGVnZW5kID0gbGlzdChmb250ID0gbGlzdChzaXplID0gNikpKSAlPiUgDQogICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkNCmBgYA0KPiBQcm9ncmVzcyBpbiByZWNlbnQgbW9udGhzIGhhcyBsYXJnZWx5IGJlZW4gZHVlIHRvIHRoZSBkaXN0cmlidXRpb24gb2YgZWR1Y2F0aW9uIGtpdHMgYW5kIGRpc3RhbmNlIGxlYXJuaW5nLiANCg0KJm5ic3A7DQoNCiMjIDQuIFN1bW1hcmllcyBieSBnZW9ncmFwaHkNCg0KIyMjIDRhLiBCZW5lZmljaWFyaWVzIGJ5IHN0YXRlDQoNCmBgYHtyIFBMT1QtYmVuZWZpY2lhaXJpZXMtYnktc3RhdGV9DQp1X2JlbjIgJT4lIA0KICBncm91cF9ieShlc3RhZG8pICU+JSANCiAgc3VtbWFyaXNlKGJlbmVmaWNpYXJpb3MgPSBzdW0oYmVuZWZpY2lhcmlvcykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfcmVvcmRlcihlc3RhZG8sIGJlbmVmaWNpYXJpb3MsIC5kZXNjID0gVFJVRSksIA0KICAgICAgICAgICAgIHkgPSBiZW5lZmljaWFyaW9zKSkgKw0KICBnZW9tX2NvbChmaWxsID0gImNvcm5mbG93ZXJibHVlIikgKw0KICB5bGltKDAsIDg1MDAwMCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpjb21tYShiZW5lZmljaWFyaW9zLCBhY2N1cmFjeSA9IDEpKSwgDQogICAgICAgICAgICB2anVzdCA9IC0wLjI1LCBoanVzdCA9IDAuMDUsIHNpemUgPSAzLCBhbmdsZSA9IDMwKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSB1bml0X2Zvcm1hdCh1bml0ID0gIksiLCBzY2FsZSA9IDFlLTMsIHNlcCA9ICIiKSwgDQogICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDAsIDIwMDAwMCkpICsNCiAgeGxhYigiIikgKyB5bGFiKCJCZW5lZmljaWFyaW9zIikgKyANCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQombmJzcDsNCg0KYGBge3IgUkVGLWZvci11YmljYWNpb24tdGV4dH0NCm1pcmFfenVsIDwtIHVfYmVuMiAlPiUgZmlsdGVyKGVzdGFkbyA9PSAiTUlSQU5EQSIgfCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzdGFkbyA9PSAiWlVMSUEiKQ0KYGBgDQoNCiMjIyA0Yi4gTnVtYmVyIG9mIHNjaG9vbHMgYnkgc3RhdGUNCj4gQSB0b3RhbCBvZiBfX2ByIGZvcm1hdChuX2Rpc3RpbmN0KHVfYmVuMiR1YmljYWNpb24pLCBiaWcubWFyayA9ICIsIilgX18gc2Nob29scyBoYXZlIGJlZW4gcmVhY2hlZCBieSBVTklDRUY7IF9fYHIgcm91bmQoKG5fZGlzdGluY3QobWlyYV96dWwkdWJpY2FjaW9uKSkgLyAobl9kaXN0aW5jdCh1X2JlbjIkdWJpY2FjaW9uKSkgKiAxMDApYCVfXyBhcmUgZnJvbSBNaXJhbmRhIGFuZCBadWxpYSBhbG9uZS4gDQoNCmBgYHtyIFBMT1Qtb2YtdWJpY2FjaW9uLWJ5LXN0YXRlfQ0KdV9iZW4yICU+JSANCiAgZ3JvdXBfYnkoZXN0YWRvKSAlPiUgDQogIGRpc3RpbmN0KHViaWNhY2lvbikgJT4lIA0KICBzdW1tYXJpc2UodWJpY2FjaW9uID0gbigpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZjdF9yZW9yZGVyKGVzdGFkbywgdWJpY2FjaW9uLCAuZGVzYyA9IFRSVUUpLCB5ID0gdWJpY2FjaW9uKSkgKw0KICBnZW9tX2NvbChmaWxsID0gImNvcm5mbG93ZXJibHVlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQodWJpY2FjaW9uKSksIHZqdXN0ID0gLTAuMjUsIHNpemUgPSAzKSArIA0KICB4bGFiKCIiKSArIHlsYWIoIk51bWVybyBkZSBFc2N1ZWxhcyIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQoNCiZuYnNwOw0KDQpgYGB7ciBSRUYtZm9yLWFsbF9tdW59DQojIGNyZWF0aW5nIHRoZSBhbGxfbXVuIGRmDQojIGFsbF9tdW4gaXMgb25lIG9icyBwZXIgcGNvZGUyDQphbGxfbXVuIDwtIHVfYmVuMiAlPiUgDQogIG11dGF0ZShpc19tYXRyaWMgPSBjYXNlX3doZW4oICMgZm9yIGJlbmVmaWNpYXJpZXMgYWdlZCAzLTE3DQogICAgICAgIHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwiM182JCIpIH4gIm1hdHJpYyIsDQogICAgICAgIHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwiN18xMiQiKSB+ICJtYXRyaWMiLA0KICAgICAgICBzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sIjEyXzE3JCIpIH4gIm1hdHJpYyIsDQogICAgICAgIFRSVUUgfiAibm9uX21hdHJpYyIpKSAlPiUgDQogIG11dGF0ZShiZW5lZmljaWFyaW9zXzNfMTcgPSBpZmVsc2UoaXNfbWF0cmljID09ICJtYXRyaWMiLCBiZW5lZmljaWFyaW9zLCAwKSkgJT4lIA0KICBncm91cF9ieShlc3RhZG8sIG11bmljaXBpbywgcGNvZGUyKSAlPiUgDQogIHN1bW1hcmlzZShiZW5lZmljaWFyaW9zID0gcm91bmQoc3VtKGJlbmVmaWNpYXJpb3MpKSwNCiAgICAgICAgICAgIGJlbmVmaWNpYXJpb3NfM18xNyA9IHJvdW5kKHN1bShiZW5lZmljaWFyaW9zXzNfMTcpKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGxlZnRfam9pbihhY3RfYmVuICU+JSAjIGJyaW5naW5nIGFjdGl2aXR5IGNvdW50cyBpbnRvIHVfYmVuDQogICAgICAgICAgICBncm91cF9ieShwY29kZTIpICU+JSANCiAgICAgICAgICAgIHN1bW1hcmlzZShhY3RfdHlwZXMgPSBuX2Rpc3RpbmN0KGFjdGl2aWRhZF9jb2RpZ28pKSkgJT4lIA0KICByaWdodF9qb2luKGNlbl9yZWYgJT4lICMgZm9yIGJyaW5naW5nIG1hdHJpY3VsYTIwMTcgaW50byBhbGxfbXVuDQogICAgICAgICAgICBwaXZvdF9sb25nZXIoY29scyA9IGMoIm1hdHJpY3VsYV8yMDE3X2VkdWNhY2lvbl9pbmljaWFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fcHJpbWFyaWEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fbWVkaWEiKSwgDQogICAgICAgICAgICAgICAgICAgICBuYW1lc190byA9ICJhZ2VfYmVuIiwgdmFsdWVzX3RvID0gIm1hdHJpY3VsYTIwMTciLCANCiAgICAgICAgICAgICAgICAgICAgIHZhbHVlc19kcm9wX25hID0gVFJVRSkgJT4lIA0KICAgICAgICAgICAgc2VsZWN0KHBjb2RlMiwgYWdlX2JlbiwgbWF0cmljdWxhMjAxNykgJT4lIA0KICAgICAgICAgICAgZ3JvdXBfYnkocGNvZGUyKSAlPiUgDQogICAgICAgICAgICBzdW1tYXJpc2UobWF0cmljdWxhMjAxNyA9IHN1bShtYXRyaWN1bGEyMDE3KSkpICU+JSANCiAgbXV0YXRlKGNvdmVyYWdlX3BlcmNlbnQgPSByb3VuZChiZW5lZmljaWFyaW9zXzNfMTcgLyBtYXRyaWN1bGEyMDE3ICogMTAwKSkgJT4lIA0KICBtdXRhdGUoZXN0YWRvID0gZmN0X3Jlb3JkZXIoZXN0YWRvLCBiZW5lZmljaWFyaW9zLCAuZGVzYyA9IFRSVUUpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhiZW5lZmljaWFyaW9zKSkNCmBgYA0KDQojIyMgNGMuIFNjYXR0ZXJwbG90IG9mIG11bmljaXBhbGl0aWVzDQoqbG9nYXJpdGhtaWMgc2NhbGU7IGxhcmdlciBwb2ludHMgaW5kaWNhdGUgbW9yZSBiZW5lZmljaWFyaWVzIHJlYWNoZWQsIGRhcmtlciBibHVlcyBpbmRpY2F0ZSBtb3JlIGFjdGl2aXR5IHR5cGVzKiANCg0KKm1vdXNlIG92ZXIgbXVuaWNpcGFsaXRpZXMgdG8gc2VlIGJlbmVmaWNpYXJpZXMgYW5kIGRpc3RpbmN0IGFjdGl2aXRpZXMqDQoNCj4gQSB0b3RhbCBvZiBfX2ByIG5fZGlzdGluY3QodV9iZW4yJHBjb2RlMilgX18gbXVuaWNpcGFsaXRpZXMgd2VyZSByZWFjaGVkIGJ5IHRoZSBVTklDRUYgRWR1Y2F0aW9uIHByb2dyYW1tZS4NCg0KYGBge3Igc2NhdHRlci1QTE9UTFktb2YtbXVuaWNpcGFsaXRpZXMtYnktc3RhdGUsIGZpZy53aWR0aD05fQ0KDQphbGxfbXVuX3BvaW50cyA8LSBhbGxfbXVuICU+JSANCiAgZ2dwbG90KGFlcyh0ZXh0ID0gbXVuaWNpcGlvLCB4ID0gZXN0YWRvLCB5ID0gYmVuZWZpY2lhcmlvcywgDQogICAgICAgICAgICAgY29sb3VyID0gYWN0X3R5cGVzKSkgKw0KICBnZW9tX3BvaW50KGFlcyhzaXplID0gYmVuZWZpY2lhcmlvcyksIGFscGhhID0gMC45KSArDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudChsb3cgPSAiYXp1cmU0IiwgaGlnaCA9ICJkYXJrYmx1ZSIpICsgI2ZpbmQgYSBiZXR0ZXIgY29sb3VyPw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCANCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGNvbW1hKSArDQogIHhsYWIoIiIpICsgeWxhYigiQmVuZWZpY2lhcmlvcyBBbGNhbnphZG9zIHBvciBNdW5pY2lwaW8iKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSANCg0KZ2dwbG90bHkoYWxsX211bl9wb2ludHMsIHRvb2x0aXAgPSBjKCJ0ZXh0IiwgInkiLCAiY29sb3VyIikpICU+JSANCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpDQoNCmBgYA0KDQombmJzcDsNCg0KIyMjIDRkLiBUb3AgMTAgbXVuaWNpcGFsaXRpZXMgYnkgcmVhY2ggYW5kIGNvdmVyYWdlDQoNCmBgYHtyIG11bmljaXBhbGl0aWVzLXRvcC1UQUJMRX0NCiMgdG9wIG11bmljaXBhbGl0aWVzIHRhYmxlDQp0b3BfbXVuIDwtIGFsbF9tdW4gJT4lIHNlbGVjdChlc3RhZG8sIG11bmljaXBpbywgYmVuZWZpY2lhcmlvcykgJT4lIHNsaWNlKDE6MTApDQoNCiMgdHJ5IHRvIG1ha2UgYSB0YWJsZSBvZiB0aGUgbW9zdCBvdmVyc3Vic2NyaWJlZCBtdW5pY2lwYWxpdGllcw0KdG9wX2NvdiA8LSBhbGxfbXVuICU+JSANCiAgYXJyYW5nZShkZXNjKGNvdmVyYWdlX3BlcmNlbnQpKSAlPiUgDQogIHNlbGVjdChlc3RhZG8sIG11bmljaXBpbywgY292ZXJhZ2VfcGVyY2VudCkgJT4lIHNsaWNlKDE6MTApDQoNCiMgdHdvIHRhYmxlcyBzaWRlIGJ5IHNpZGUNCmthYmxlKHRvcF9tdW4sIGNhcHRpb24gPSAiYnkgYmVuZWZpY2lhcmllcyIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gImJvcmRlcmVkIiwgZnVsbF93aWR0aCA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICBwb3NpdGlvbiA9ICJmbG9hdF9sZWZ0IiwgZm9udF9zaXplID0gMTIpDQprYWJsZSh0b3BfY292LCBjYXB0aW9uID0gImJ5IGNvdmVyYWdlIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAiYm9yZGVyZWQiLCBmdWxsX3dpZHRoID0gRkFMU0UsIA0KICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gImxlZnQiLCBmb250X3NpemUgPSAxMikNCmBgYA0KDQpgYGB7ciBSRUYtZm9yLXRleHQtYmVsb3d9DQojIHN1bSBvZiB0b3AgdGVuDQp0b3BfbXVuX3N1bSA8LSBhbGxfbXVuICU+JSANCiAgc2xpY2UoMToxMCkgJT4lIHN1bW1hcmlzZShzdW0gPSBzdW0oYmVuZWZpY2lhcmlvcywgbmEucm0gPSBUUlVFKSkNCg0KYWxsX211bl9zdW0gPC0gYWxsX211biAlPiUgDQogIHN1bW1hcmlzZShzdW0gPSBzdW0oYmVuZWZpY2lhcmlvcywgbmEucm0gPSBUUlVFKSkNCmBgYA0KDQo+IFRvZ2V0aGVyLCB0aGUgMTAgbXVuaWNpcGFsaXRpZXMgd2l0aCB0aGUgaGlnaGVzdCByZWFjaCAoYWJvdmUgbGVmdCkgZm9ybSBfX2ByIHJvdW5kKHRvcF9tdW5fc3VtIC8gYWxsX211bl9zdW0gKiAxMDApYCVfXyBvZiB0aGUgX19gciBmb3JtYXQocm91bmQoc3VtKHVfYmVuMiRiZW5lZmljaWFyaW9zKSksIGJpZy5tYXJrID0gIiwiKWBfXyBiZW5lZmljaWFyaWVzIHJlYWNoZWQuIFRoZSBhdmVyYWdlIGNvdmVyYWdlIG9mIHRoZSBzY2hvb2wtYWdlIHBvcHVsYXRpb24gaW4gdGhlIG11bmljaXBhbGl0aWVzIHdoZXJlIFVOSUNFRiBpcyBwcmVzZW50IGlzIF9fYHIgcm91bmQobWVhbihhbGxfbXVuJGNvdmVyYWdlX3BlcmNlbnQsIG5hLnJtID0gVFJVRSkpYCVfXy4gQ292ZXJhZ2UgcmVmZXJzIHRvIHRoZSBwZXJjZW50YWdlIG9mIGVucm9sbGVkIGNoaWxkcmVuIChhZ2VkIDMtMTcgeWVhcnMpIHJlYWNoZWQgYnkgVU5JQ0VGLiANCg0KJm5ic3A7DQoNCiMjIyA0ZS4gSGlzdG9ncmFtIG9mIENvdmVyYWdlDQoNCj4gQmVsb3cgaXMgYSBoaXN0b2dyYW0gb2YgbXVuY2lpcGFsaXRpZXMgd2hlcmUgVU5JQ0VGIGlzIHByZXNlbnQgc2hvd2luZyB0aGUgY292ZXJhZ2Ugb2YgZW5yb2xsZWQgY2hpbGRyZW4gKGFnZWQgMy0xNykuIE9mIG5vdGUsIHdlIGhhdmUgcmVhY2hlZCAxMCUgb3IgbGVzcyBvZiB0aGUgcG9wdWxhdGlvbiBpbiBfX2ByIHN1bShhbGxfbXVuJGNvdmVyYWdlX3BlcmNlbnQgPD0gMTAsIG5hLnJtID0gVFJVRSlgX18gb3V0IG9mIHRoZSBfX2ByIG5fZGlzdGluY3QodV9iZW4yJHBjb2RlMilgX18gaW4gd2hpY2ggd2Ugb3BlcmF0ZS4gVGhpcyBpcyBpbiBhZGRpdGlvbiB0byB0aGUgX19gciBzdW0oaXMubmEoYWxsX211biRjb3ZlcmFnZV9wZXJjZW50KSlgX18gd2hlcmUgbm8gVU5JQ0VGIEVkdWNhdGlvbiBhY3Rpdml0aWVzIGhhdmUgb2NjdXJyZWQuIA0KDQpgYGB7ciBQTE9ULWhpc3RvZ3JhbS1vZi1jb3ZlcmFnZX0NCmFsbF9tdW4gJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBjb3ZlcmFnZV9wZXJjZW50KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEwLCBjb2xvdXIgPSAiYmxhY2siLCBmaWxsID0gIndoaXRlIikgKw0KICBzdGF0X2JpbihiaW53aWR0aCA9IDEwLCBnZW9tID0gInRleHQiLCBhZXMobGFiZWwgPSAuLmNvdW50Li4pLCB2anVzdCA9IC0wLjUpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMTAsIDIwLCAzMCwgNDAsIDUwLCA2MCwgNzAsIDgwLCA5MCkpICsNCiAgeWxhYigiTnVtYmVyIG9mIG11bmljaXBhbGl0aWVzIikgKyB4bGFiKCJQZXJjZW50IG9mIGVucm9sbGVkIGNoaWxkcmVuICgzLTE3KSBjb3ZlcmVkIikNCg0KYGBgDQoNCiZuYnNwOw0KDQojIyA1LiBSZXBvcnRzIGFib3V0IHBhcnRuZXJzDQoNCiMjIyA1YS4gU3VtbWFyeSBieSBwYXJ0bmVyDQoNCmBgYHtyIFBMT1RMWS1zdGFja2VkLWJhci1wYXJ0bmVyLCBmaWcud2lkdGg9OX0NCiMgZm9yIHRoZSB0b3RhbHMgcGVyIHBhcnRuZXIgc2hvd3MgaW4gdGhlIGdlb21fdGV4dCBiZWxvdw0Kc3RhY2tfdGV4dCA8LSBhY3RfYmVuMiAlPiUgDQogIGdyb3VwX2J5KG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWwgPSBzdW0oYmVuZWZpY2lhcmlvcykpICU+JSANCiAgYXJyYW5nZShkZXNjKHRvdGFsKSkNCg0KIyB2ZWN0b3IgZm9yIG9yZGVyaW5nIG9mIHgtYXhpcyAocGFydG5lcnMpDQpvcmRfc29jIDwtIGMoIlVOSUNFRiIsICJTT0NJTyAxIiwgIlNPQ0lPIDIiLCAiU09DSU8gNCIsICJTT0NJTyA1IiwgIlNPQ0lPIDciLCAiU09DSU8gOCIsDQogICAgICAgICAgICAgIlNPQ0lPIDMiLCAiU09DSU8gMTAiLCAiU09DSU8gNiIpDQoNCiMgY3JlYXRpbmcgdGhlIHBsb3QNCnNvY19zdGFjayA8LSBhY3RfYmVuMiAlPiUgDQogIGdyb3VwX2J5KGFjdGl2aWRhZF9zaG9ydCwgb3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhKSAlPiUgDQogIHN1bW1hcmlzZShiZW5lZmljaWFyaW9zID0gcm91bmQoc3VtKGJlbmVmaWNpYXJpb3MpKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSwgDQogICAgICAgICAgICAgeSA9IGJlbmVmaWNpYXJpb3MpKSArDQogIGdlb21fY29sKGFlcyhmaWxsID0gYWN0aXZpZGFkX3Nob3J0KSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gdW5pdF9mb3JtYXQodW5pdCA9ICJLIiwgc2NhbGUgPSAxZS0zLCBzZXAgPSAiIiksIA0KICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCA0MDAwMDApKSArDQogIHhsYWIoIiIpICsgeWxhYigiQmVuZWZpY2lhcmlvcyIpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksDQogICAgICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC4xLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWUgPSAiQWN0aXZpZGFkIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IHN0YWNrX3RleHQsIGFlcyh5ID0gdG90YWwgKyA2MDAwLCBsYWJlbCA9IHNjYWxlczo6Y29tbWEodG90YWwpKSwgDQogICAgICAgICAgICBzaXplID0gMykgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IG9yZF9zb2MpDQoNCmdncGxvdGx5KHNvY19zdGFjaywgdG9vbHRpcCA9IGMoIngiLCAiZmlsbCIsICJ5IikpICU+JSANCiAgbGF5b3V0KGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSAiPGI+IG9yZ2FuaXphY2lvbiA8Yj4iKSkpICU+JSANCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpICU+JSANCiAgbGF5b3V0KHNob3dsZWdlbmQgPSBUUlVFLCBsZWdlbmQgPSBsaXN0KGZvbnQgPSBsaXN0KHNpemUgPSA2KSkpDQoNCmBgYA0KDQombmJzcDsNCg0KIyMjIDViLiBOdW1iZXIgb2YgYWN0aXZpdHkgdHlwZXMgaW1wbGVtZW50ZWQgYnkgZWFjaCBwYXJ0bmVyDQoNCmBgYHtyIFRBQkxFLXBhcnRuZXItYWN0aXZpdHktY291bnR9DQojIHRoaXMgaW5jbHVkZXMgQ0ExLjA1DQphY3RfYmVuICU+JSANCiAgbXV0YXRlKG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSA9IA0KICAgICAgICAgICBzdHJfcmVwbGFjZV9hbGwob3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJVTklDRUYgLSBGb25kbyBkZSBsYXMgTmFjaW9uZXMgVW5pZGFzIHBhcmEgbGEgSW5mYW5jaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVOSUNFRiIpKSAlPiUgDQogIHJlbmFtZShwYXJ0bmVyID0gb3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhKSAlPiUgDQogIGdyb3VwX2J5KHBhcnRuZXIpICU+JSANCiAgc3VtbWFyaXNlKGFjdF90eXBlcyA9IG5fZGlzdGluY3QoYWN0aXZpZGFkX2NvZGlnbykpICU+JSANCiAgYXJyYW5nZShkZXNjKGFjdF90eXBlcykpICU+JSANCiAgdCgpICU+JSANCiAgcGFuZGVyKCkNCg0KYGBgDQoNCiZuYnNwOw0KDQojIyMgNWMuIFBhcnRuZXJzJyBwcm9ncmVzcyBvdmVyIHRpbWUNCiptb3VzZSBvdmVyIGZvciBkZXRhaWxzKg0KDQpgYGB7ciBsaW5lLVBMT1RMWS1wYXJ0bmVycy1wcm9ncmVzcywgZmlnLndpZHRoPTl9DQoNCnNvY19saW5lIDwtIGFjdF9iZW4yICU+JSANCiAgbXV0YXRlKG1lc19zb2xvID0gYXMuRGF0ZShtZXNfc29sbykpICU+JSANCiAgZ3JvdXBfYnkob3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCBtZXNfc29sbykgJT4lIA0KICBzdW1tYXJpc2UoY3VtdWxhdGl2ZSA9IHJvdW5kKHN1bShiZW5lZmljaWFyaW9zKSkpICU+JSANCiAgbXV0YXRlKGN1bXVsYXRpdmUgPSBjdW1zdW0oY3VtdWxhdGl2ZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVzX3NvbG8sIHkgPSBjdW11bGF0aXZlLCBjb2xvdXIgPSBvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEpKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMC43KSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlYi0lWSIsIGRhdGVfYnJlYWtzID0gIjEgbW9udGgiKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSB1bml0X2Zvcm1hdCh1bml0ID0gIksiLCBzY2FsZSA9IDFlLTMsIHNlcCA9ICIiKSwgDQogICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDAsIDQxMDAwMCkpICsNCiAgeGxhYigiIikgKyB5bGFiKCJCZW5lZmljaWFyaW9zIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpLA0KICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQ0KDQpnZ3Bsb3RseShzb2NfbGluZSwgdG9vbHRpcCA9IGMoIngiLCAieSIsICJjb2xvdXIiKSkgJT4lIA0KICBsYXlvdXQobGVnZW5kID0gbGlzdCh0aXRsZSA9IGxpc3QodGV4dCA9ICI8Yj4gb3JnYW5pemFjaW9uIDxiPiIpKSkgJT4lIA0KICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkNCiAgDQpgYGANCg0KJm5ic3A7DQoNCiMjIyA1ZC4gU3VtbWFyeSB0YWJsZSBvZiBwYXJ0bmVycycgYWNoaWV2ZW1lbnRzDQoNCmBgYHtyIFRBQkxFLXBhcnRuZXJzLXN1bW1hcnl9DQphY3RfYmVuMiAlPiUgDQogIG11dGF0ZShzZXhfYmVuID0gaWZlbHNlKHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwgIl5tIiksICJtYWxlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwgIl5mIiksICJmZW1hbGUiLCAibm9fZXNwIikpKSAlPiUgDQogIG11dGF0ZShhY3RpdmlkYWQgPSBhY3RpdmlkYWRfZGVzYykgJT4lIA0KICBncm91cF9ieShvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEpICU+JSANCiAgc3VtbWFyaXNlKG1hbGUgPSBzdW0oKGJlbmVmaWNpYXJpb3Nbc2V4X2JlbiA9PSAibWFsZSJdKSksDQogICAgICAgICAgICBmZW1hbGUgPSBzdW0oKGJlbmVmaWNpYXJpb3Nbc2V4X2JlbiA9PSAiZmVtYWxlIl0pKSwNCiAgICAgICAgICAgIHNleF9yYXRpbyA9IHJvdW5kKChtYWxlL2ZlbWFsZSksIGRpZ2l0cyA9IDIpLA0KICAgICAgICAgICAgYmVuZWZpY2lhcmlvcyA9IHN1bShiZW5lZmljaWFyaW9zLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIG11dGF0ZShwZXJjZW50X29mX3RvdGFsID0gcm91bmQoKGJlbmVmaWNpYXJpb3MgLyBzdW0oYmVuZWZpY2lhcmlvcykgKiAxMDApLCBkaWdpdHMgPSAyKSkgJT4lIA0KICBsZWZ0X2pvaW4oYWN0X2JlbiAlPiUgDQogICAgICAgICAgICAgIG11dGF0ZShvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEgPSANCiAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiVU5JQ0VGIC0gRm9uZG8gZGUgbGFzIE5hY2lvbmVzIFVuaWRhcyBwYXJhIGxhIEluZmFuY2lhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJVTklDRUYiKSkgJT4lIA0KICAgICAgICAgICAgICBncm91cF9ieShvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEpICU+JSANCiAgICAgICAgICAgICAgc3VtbWFyaXNlKG11bmljaXBhbGl0aWVzID0gbl9kaXN0aW5jdChwY29kZTIpKSwgDQogICAgIGJ5ID0gIm9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSIpICU+JSANCiAgcmVsb2NhdGUoYmVuZWZpY2lhcmlvcywgLmFmdGVyID0gb3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhKSAlPiUgDQogIHJlbG9jYXRlKHBlcmNlbnRfb2ZfdG90YWwsIC5hZnRlciA9IGJlbmVmaWNpYXJpb3MpICU+JSANCiAgYXJyYW5nZShkZXNjKGJlbmVmaWNpYXJpb3MpKSAlPiUgDQogIHBhbmRlcihiaWcubWFyayA9ICIsIiwgc3R5bGUgPSAicm1hcmtkb3duIikNCmBgYA0KDQombmJzcDsNCg0KIyMgNi4gTWFwcyBhbmQgcmVmZXJlbmNlIHRhYmxlDQoNCiZuYnNwOw0KDQojIyMgNmEuIE1hcHMgYXQgbXVuaWNpcGFsIGxldmVsDQoNCmBgYHtyIE1BUFMtbXVuLXJlYWNoZWQtYW5kLXBlcmNlbnQtcmVhY2hlZH0NCg0KIyByZWFkaW5nIGluIHNoYXBlZmlsZQ0KIyBxdWlldCA9IFRSVUUgaXMgdmVyeSBpbXBvcnRhbnQgaGVyZQ0KcGNvZGUyX3NoYXBlIDwtIHN0X3JlYWQoIkM6L1VzZXJzL1NlYW4gTmcvRG9jdW1lbnRzL1IvNVcvdm56X2FkbTJfc2hhcGVmaWxlcy92ZW5fYWRtYm5kYV9hZG0yXzIwMTgwNTAyLnNocCIsIHF1aWV0ID0gVFJVRSkgJT4lIA0KICByZW5hbWUocGNvZGUxID0gQURNMV9QQ09ERSwNCiAgICAgICAgIHBjb2RlMiA9IEFETTJfUENPREUpDQoNCiMgSSB0aGluayBwbG90bHkncyBzZWxlY3RvciB0b29sIGlzIG5vdCB2ZXJ5IGdvb2QuIG9yIG1heWJlIHRoZSBjZW50cm9pZHMNCiMgb2YgdGhlIHZlbl9hZG1ibmRhIGRhdGFzZXQgaXMgbm90IHZlcnkgZ29vZCwgYXQgbGVhc3Qgd2hlbiBpdCBjb21lcyB0byBjZW50cm9pZHMuIA0KDQojIHBsb3QgZm9yIGJlbmVmaWNpYXJpZXMgcmVhY2hlZCBieSBwY29kZTINCm11bl9iZW5fcGxvdCA8LSBhbGxfbXVuICU+JSANCiAgcmlnaHRfam9pbihwY29kZTJfc2hhcGUpICU+JSANCiAgc3RfYXNfc2YoKSAlPiUgDQogIGdncGxvdChhZXMoZmlsbCA9IGJlbmVmaWNpYXJpb3MpKSArDQogIGdlb21fc2Yoc2l6ZSA9IDAuMDEpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgZ2d0aXRsZSgiTnVtYmVyIG9mIGJlbmVmaWNpYXJpZXMgcmVhY2hlZCBieSBtdW5pY2lwYWxpdHkiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQodHJhbnMgPSB0cmFuc19yZXZlcnNlcigibG9nIiksIGJyZWFrcyA9IGMoMCwgMTAwLCAxMDAwLCAxMDAwMCwgODA0ODIpLA0KICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGNvbW1hLCBuYS52YWx1ZSA9ICJncmF5OTAiKSArDQogIHRoZW1lKGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC4zLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjksIDAuMSksDQogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KDQojIG1hcCBvZiBwZXJjZW50IG9mIGVucm9sbGVkIGNoaWRyZW4gY292ZXJlZCBieSBwY29kZTINCm11bl9wZXJjZW50X3Bsb3QgPC0gYWxsX211biAlPiUgDQogIHJpZ2h0X2pvaW4ocGNvZGUyX3NoYXBlKSAlPiUgDQogIHN0X2FzX3NmKCkgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IGNvdmVyYWdlX3BlcmNlbnQpKSsNCiAgZ2VvbV9zZihzaXplID0gMC4wMSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICBnZ3RpdGxlKCJQZXJjZW50IG9mIGVucm9sbGVkIGNoaWxkcmVuICgzLTE3KSByZWFjaGVkIGJ5IG11bmljaXBhbGl0eSIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsYWJlbHMgPSBjb21tYSwgdHJhbnMgPSAicmV2ZXJzZSIsIG5hLnZhbHVlID0gImdyYXk5MCIpKw0KICB0aGVtZShsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuMywgImNtIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45LCAwLjEpLA0KICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpDQoNCiMgdXNpbmcgcGF0Y2h3b3JrIHRvIHB1dCB0aGVtIHNpZGUgYnkgc2lkZSANCm11bl9iZW5fcGxvdCArIG11bl9wZXJjZW50X3Bsb3QgKyBwbG90X2xheW91dChuY29sID0gMikNCmBgYA0KDQombmJzcDsNCg0KIyMjIDZiLiBSZWZlcmVuY2UgdGFibGUgLS0gbXVuaWNpcGFsIGxldmVsDQoNCl9fdXNlIGBVTklDRUZfcHJlc2VudGAgdG8gZmlsdGVyIHRvIG11bmljaXBhbGl0aWVzIHdoZXJlIHRoZSBFZHVjYXRpb24gcHJvZ3JhbW1lIG9wZXJhdGVzX18NCg0KKkNBMDEuMDUgUHJvbW9jaW9uIGRlIG1lbnNhamVzIGNsYXZlcyBwYXJhIGxhIGNvbXVuaWRhZCBlc2NvbGFyIGlzIG5vdCBpbmNsdWRlZCoNCg0KYGBge3IgRFQtZGF0YXRhYmxlfQ0KDQojIGl0IHNob3dzIDMzNSwgc2hvdWxkbid0IHRoZXJlIGJlIDMzNj8gSSBiZXQgaXQncyBWYXJnYXMgYWdhaW4NCmFsbF9tdW4gJT4lIA0KICBtdXRhdGUoVU5JQ0VGX3ByZXNlbnQgPSBpZmVsc2UoaXMubmEoYmVuZWZpY2lhcmlvcyksIEZBTFNFLCBUUlVFKSkgJT4lIA0KICByZW5hbWUobm9fb2ZfYWN0aXZpdGllcyA9IGFjdF90eXBlcykgJT4lICMgSSBmZWVsIGxpa2UgeW91IHNob3VsZCBoYXZlIGRvbmUgdGhpcyBlYXJsaWVyDQogIGxlZnRfam9pbihjZW5fcmVmICU+JSAjIGFkZGl0aW9uYWwgY2Vuc3VzIHZhcmlhYmxlcw0KICAgICAgZ3JvdXBfYnkocGNvZGUyKSAlPiUgDQogICAgICBzdW1tYXJpc2UocG9vcl9wZXJzb25zID0gcm91bmQoc3VtKGhhbV8yMDE5X3h4X3BvYmxhY2lvbl9wb2JyZV9wb3JfcGFycm9xdWlhKSksDQogICAgICAgICAgICAgICAgdG90YWxfcG9wICAgID0gc3VtKHhfMjAxOV9wb2JsYWNpb25fcGFycm9xdWlhbF90b3RhbCkpICU+JSANCiAgICAgIG11dGF0ZShwb3ZlcnR5X2luY2lkZW5jZSA9IHJvdW5kKHBvb3JfcGVyc29ucyAvIHRvdGFsX3BvcCAqIDEwMCkpKSAlPiUgDQogIHNlbGVjdCghcGNvZGUyKSAlPiUNCiAgcmVsb2NhdGUoVU5JQ0VGX3ByZXNlbnQpICU+JSANCiAgcmVsb2NhdGUocG92ZXJ0eV9pbmNpZGVuY2UsIC5hZnRlciA9IGNvdmVyYWdlX3BlcmNlbnQpICU+JSANCiAgcmVsb2NhdGUobm9fb2ZfYWN0aXZpdGllcywgLmFmdGVyID0gcG92ZXJ0eV9pbmNpZGVuY2UpICU+JQ0KICBkYXRhdGFibGUoZmlsdGVyID0gInRvcCIsIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCwgc2Nyb2xsWCA9IFRSVUUpKSAlPiUgDQogIERUOjpmb3JtYXRTdHlsZShjb2x1bW5zID0gY29sbmFtZXMoLiksIGZvbnRTaXplID0gIjEycHQiKQ0KICANCmBgYA0KDQo=
=======
LS0tDQp0aXRsZTogIkNsZWFuaW5nIGFuZCBSZXBvcnRpbmcgb24gRWR1Y2F0aW9uIDVXIGRhdGEgZnJvbSBWZW5lenVlbGEiDQphdXRob3I6ICJTZWFuIE5nIg0KZGF0ZTogIjEyIE5vdmVtYmVyLCAyMDIxIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRvY19kZXB0aDogNA0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiByZWFkYWJsZQ0KLS0tDQoNCiMgQS4gQ2xlYW5pbmcgdGhlIDVXIGRhdGENCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGggPSA5LjUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShzdHJpbmdyKQ0KbGlicmFyeShzdHJpbmdpKQ0KbGlicmFyeShwYW5kZXIpDQpsaWJyYXJ5KHNjYWxlcykNCmxpYnJhcnkoZm9yY2F0cykNCmxpYnJhcnkoamFuaXRvcikNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShnZ21hcCkNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KHBhdGNod29yaykNCmxpYnJhcnkobWFwdG9vbHMpDQpsaWJyYXJ5KGdnZm9yY2UpDQpsaWJyYXJ5KGdndGhlbWVzKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KERUKQ0KbGlicmFyeSh0aW55dGV4KQ0KDQojIHRhYmxlcyBhbGwgaW4gb25lIHJvdw0KcGFuZGVyT3B0aW9ucygndGFibGUuc3BsaXQudGFibGUnLCBJbmYpDQoNCiMgdGhvdXNhbmRzIHNlcGFyYXRvcg0KcGFuZGVyT3B0aW9ucygiYmlnLm1hcmsiLCAiLCIpDQoNCmBgYA0KDQoNCj4gVGhpcyBmaXJzdCBzZWN0aW9uIGRldGFpbHMgYW4gZXhhbXBsZSBvZiB0aGUgY29kZSBuZWNlc3NhcnkgZm9yIGNsZWFuaW5nIGEgNVcgZGF0YXNldCBpbiBSLiA1VyBkYXRhIGlzIHR5cGljYWxseSBtZXNzeSBhbmQgaW4gd2lkZSBmb3JtYXQuIEFkZGl0aW9uYWxseSwgZGF0YSB3cmFuZ2xpbmcgaXMgdGltZSBjb25zdW1pbmcgYW5kIGFuIGluZWZmaWNpZW50IHVzZSBvZiBhIHNwZWNpYWxpc3QncyB0aW1lLiBUaGUgY29kZSBwcmVzZW50ZWQgYmVsb3cgaW50ZW5kcyB0byBkZW1vbnN0cmF0ZSB0aGF0IHRoaXMgbW9udGhseSAob3Igc29tZXRpbWVzIG1vcmUgZnJlcXVlbnQpIG9jY3VyZW5jZSBjYW4gYmUgZ3JlYXRseSBhdXRvbWF0ZWQsIGFsbG93aW5nIGZvciBtb3JlIHRpbWVseSBhbmQgYWNjdXJhdGUgYW5hbHlzaXMgYXMgd2VsbCBhcyBjcmVhdGluZyB0aGUgc3BhY2UgZm9yIG1vcmUgdGFpbG9yZWQgcmVwb3J0aW5nLiAgDQoNCiZuYnNwOw0KDQojIyAxLiBSZWFkaW5nIGluIHRoZSBkYXRhc2V0DQoNCmBgYHtyIHJlYWRpbmctaW4teGxzeCwgZWNobz1UUlVFfQ0KIyBzcGVjaWZ5aW5nIGNvbHVtbiB0eXBlcyANCmFjdF9jb2xfdHlwZXMgPC0gYygiZGF0ZSIsICJkYXRlIiwgInRleHQiLCAidGV4dCIsInRleHQiLCJ0ZXh0IiwNCiAgICAgICAgICAgICAgICAgICAidGV4dCIsInRleHQiLCJ0ZXh0IiwidGV4dCIsInRleHQiLCJ0ZXh0IiwidGV4dCIsDQogICAgICAgICAgICAgICAgICAgIm51bWVyaWMiLCAibnVtZXJpYyIsICJ0ZXh0IiwidGV4dCIsInRleHQiLA0KICAgICAgICAgICAgICAgICAgICJ0ZXh0IiwidGV4dCIsInRleHQiLCAibnVtZXJpYyIsICJ0ZXh0IiwgDQogICAgICAgICAgICAgICAgICAgImRhdGUiLCAiZGF0ZSIsICJ0ZXh0IiwgIm51bWVyaWMiLCAibnVtZXJpYyIsDQogICAgICAgICAgICAgICAgICAgImxvZ2ljYWwiLCAibnVtZXJpYyIsICJudW1lcmljIiwgIm51bWVyaWMiLA0KICAgICAgICAgICAgICAgICAgICJudW1lcmljIiwgIm51bWVyaWMiLCAibnVtZXJpYyIsICJudW1lcmljIiwNCiAgICAgICAgICAgICAgICAgICAibnVtZXJpYyIsICJudW1lcmljIiwgIm51bWVyaWMiLCAibnVtZXJpYyIsDQogICAgICAgICAgICAgICAgICAgIm51bWVyaWMiLCAibnVtZXJpYyIsICJudW1lcmljIikNCg0KIyB5b3UncmUgZ29ubmEgaGF2ZSB0byBsaXZlIHdpdGggdGhlIGVycm9yIG1lc3NhZ2VzLA0KIyBzaW5jZSB5b3UgY2FuJ3Qgc2xpY2UgYmVmb3JlIHJlYWRfZXhjZWwoKSBhcmd1bWVudA0KDQphY3QxPC0gcmVhZF9leGNlbCgiZGF0YWJhc2UgYWN0aXZpdGllcyA1Vy54bHN4IiwgDQogICAgICAgICAgICAgICAgICAgICBzaGVldCA9ICJkYXRhIiwgDQogICAgICAgICAgICAgICAgICAgICBza2lwID0gMSwgDQogICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBhY3RfY29sX3R5cGVzKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICByZW1vdmVfZW1wdHkoKSAlPiUgDQogIHNsaWNlKC1jKDEpKSAlPiUgIyByZW1vdmVzIHRoZSBzZWNvbmQgcm93DQogIHNsaWNlKC1jKDEyMDU1KSkgIyByZW1vdmVzIHRoZSBncmFuZCB0b3RhbA0KDQpgYGANCg0KIyMjIDFhLiBSZW5hbWluZyBDb2x1bW5zIA0KDQo+IEEgYGdsaW1wc2UoKWAgb2YgdGhlIHJlbmFtZWQgZGF0YXNldDoNCg0KYGBge3J9DQphY3RfbmFtZXMgPC0gYygiZmVjaGFfcmVwb3J0YWRvX2NsdXN0ZXIiLA0KICAgICAgICAgICAgICAgIm1lc19yZXBvcnRhZG8iLA0KICAgICAgICAgICAgICAgImNvZGlnb19kZV9wcm95ZWN0byIsDQogICAgICAgICAgICAgICAibm9tYnJlX2RlbF9wcm95ZWN0byIsDQogICAgICAgICAgICAgICAib3JnYW5pemFjaW9uX2xpZGVyIiwNCiAgICAgICAgICAgICAgICJvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEiLA0KICAgICAgICAgICAgICAgImVzdGFkbyIsDQogICAgICAgICAgICAgICAicGNvZGUxIiwNCiAgICAgICAgICAgICAgICJtdW5pY2lwaW8iLA0KICAgICAgICAgICAgICAgInBjb2RlMiIsDQogICAgICAgICAgICAgICAicGFycm9xdWlhIiwNCiAgICAgICAgICAgICAgICJwY29kZTMiLA0KICAgICAgICAgICAgICAgInViaWNhY2lvbiIsDQogICAgICAgICAgICAgICAibGF0aXR1ZCIsDQogICAgICAgICAgICAgICAibG9uZ2l0dWQiLA0KICAgICAgICAgICAgICAgImFjdGl2aWRhZF9mdWxsIiwNCiAgICAgICAgICAgICAgICJhY3RpdmlkYWRfY29kaWdvIiwNCiAgICAgICAgICAgICAgICJhY3RpdmlkYWRfZGVzYyIsDQogICAgICAgICAgICAgICAiYWN0aXZpZGFkX2NvZGlnb19kZXNjIiwNCiAgICAgICAgICAgICAgICJhY3RfY292aWQiLA0KICAgICAgICAgICAgICAgInVuaWRhZCIsDQogICAgICAgICAgICAgICAiY2FudGlkYWRfZGVsX21lcyIsDQogICAgICAgICAgICAgICAicmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zIiwNCiAgICAgICAgICAgICAgICJmZWNoYV9kZV9pbmljaW8iLA0KICAgICAgICAgICAgICAgImZlY2hhX3ByZXZpc3RhX2ZpbmFsaXphY2lvbiIsDQogICAgICAgICAgICAgICAiZXN0YXR1c19hY3RpdmlkYWQiLA0KICAgICAgICAgICAgICAgInRvdGFsX2JlbmVmaWNpYXJpb3MiLA0KICAgICAgICAgICAgICAgImNoZWNrX2JlbmVmaWNpYXJpZXMiLA0KICAgICAgICAgICAgICAgInRfZl9iZW4iLA0KICAgICAgICAgICAgICAgInBlcmNlbnRfcG9ibGFjaW9uX2luZGlnZW5hIiwNCiAgICAgICAgICAgICAgICJwZXJjZW50X3BlcnNvbmFzX2Nvbl9kaXNjYXBhY2lkYWQiLA0KICAgICAgICAgICAgICAgIm1fMF8zIiwNCiAgICAgICAgICAgICAgICJtXzNfNiIsDQogICAgICAgICAgICAgICAibV83XzEyIiwNCiAgICAgICAgICAgICAgICJtXzEyXzE3IiwNCiAgICAgICAgICAgICAgICJtXzE4XzE5IiwNCiAgICAgICAgICAgICAgICJmXzBfMyIsDQogICAgICAgICAgICAgICAiZl8zXzYiLA0KICAgICAgICAgICAgICAgImZfN18xMiIsDQogICAgICAgICAgICAgICAiZl8xMl8xNyIsDQogICAgICAgICAgICAgICAiZl8xOF8xOSIsDQogICAgICAgICAgICAgICAiZl9tYXlvcmVzX2RlXzE5IiwNCiAgICAgICAgICAgICAgICJtX21heW9yZXNfZGVfMTkiKQ0KDQojIHJlbmFtZWQgDQpuYW1lcyhhY3QxKSA8LSBhY3RfbmFtZXMNCg0KZ2xpbXBzZShhY3QxKQ0KYGBgDQoNCiZuYnNwOw0KDQojIyAyLiBTdHJpbmcgTWFuaXB1bGF0aW9uIGFuZCBSZWNvZGluZyANCg0KIyMjIDJhLiBSZW1vdmluZyBhY2NlbnRzIGFuZCBzdGFuZGFyZGlzaW5nIGNhc2UNCg0KPiBXaGlsc3QgaXQgaXMgdHJ1ZSB3aGVuIHNvbWUgcGVvcGxlIHNheSB0aGF0IGlmIHlvdSByZW1vdmUgdGlsZGVzIGFuZCBvdGhlciBkaWFjcml0aWNhbCBtYXJrcywgaXQgaXQgbm8gbG9uZ2VyIGJlY29tZXMgU3BhbmlzaC4gSG93ZXZlciwgaXQgbXVzdCBiZSBzYWlkIHRoYXQgaW1wbGVtZW50aW5nIHBhcnRuZXJzIGRvbid0IGNhcmUgYW5kIGhhdmUgaW5jbHVkZWQgYSB3aWRlIHZhcmlldHkgb2Ygc3BlbGxpbmdzLiBJIHdvdWxkIHNheSB0aGF0IHJlbW92ZSBhbGwgYWNjZW50IG1hcmtzIGlzIG5lY2Vzc2FyeSB0byBjb250aW51ZSB3b3JraW5nIHdpdGggdGhlIGRhdGFzZXQuIA0KDQpgYGB7ciByZW1vdmUtYWNjZW50cywgZWNobz1UUlVFfQ0KIyBmdW5jdGlvbiB0byByZW1vdmUgYWNjZW50cw0Kcm1fYWNjZW50IDwtIGZ1bmN0aW9uKGNvbG5zKXsNCiAgY29sbnMgPC0gc3RyaV90cmFuc19nZW5lcmFsKGNvbG5zLCAiTGF0aW4tQVNDSUkiKQ0KfQ0KDQojIHJlbW92aW5nIGFjY2VudHMNCiMgYW5kIHN0cl90b191cHBlcigpIHNpbmNlIFIgaXMgY2FzZS1zZW5zaXRpdmUNCmFjdDEgPC0gYWN0MSAlPiUgDQogIG11dGF0ZShlc3RhZG8gICAgPSBybV9hY2NlbnQoc3RyX3RvX3VwcGVyKGVzdGFkbykpLCANCiAgICAgICAgIG11bmljaXBpbyA9IHJtX2FjY2VudChzdHJfdG9fdXBwZXIobXVuaWNpcGlvKSksDQogICAgICAgICBwYXJyb3F1aWEgPSBybV9hY2NlbnQoc3RyX3RvX3VwcGVyKHBhcnJvcXVpYSkpLA0KICAgICAgICAgdWJpY2FjaW9uID0gcm1fYWNjZW50KHN0cl90b191cHBlcih1YmljYWNpb24pKSwNCiAgICAgICAgIGFjdGl2aWRhZF9kZXNjID0gcm1fYWNjZW50KHN0cl90b191cHBlcihhY3RpdmlkYWRfZGVzYykpKQ0KDQpgYGANCg0KIyMjIDJiLiBSZWNvZGluZyBlcnJvbmVvdXMgZGF0YQ0KDQo+IFRoZXNlIHNob3VsZCBqdXN0IGJlIGRyb3Bkb3duIG1lbnVzOyBwYXJ0bmVycyBzaG91bGQgYWxzbyBiZSBpbmZvcm1lZCB0aGF0IGJsYW5rcyB3aWxsIGJlIHRyZWF0ZWQgYXMgRkFMU0UuIEFkZGl0aW9uYWxseSwgYSBuZXcgZGF0ZSBjb2x1bW4ganVzdCB3aXRoIHRoZSBtb250aCBpcyBtdXRhdGVkLCBhcyB0aGUgYG1lc19yZXBvcnRhZG9gIGNvbHVtbiBoYXMgc29tZSBtb250aHMgd2l0aCBtdWx0aXBsZSByZXBvcnRpbmcgZGF0ZXMuIA0KDQpgYGB7ciByZWNvZGluZywgZWNobz1UUlVFfQ0KIyByZWNvZGluZyANCmFjdDEgPC0gYWN0MSAlPiUgDQogIG11dGF0ZShyZWN1cnJlbnRlX2JlbmVmaWNpYXJpb3MgPSANCiAgICAgICAgICAgcmVjb2RlKHJlY3VycmVudGVfYmVuZWZpY2lhcmlvcywgDQogICAgICAgICAgICAibm8iID0gRkFMU0UsICJObyIgPSBGQUxTRSwgIlNpIiA9IFRSVUUsICJzaSIgPSBUUlVFLCAic8OtIiA9IFRSVUUsICJTw60iID0gVFJVRSksDQogICAgICAgICBhY3RfY292aWQgPSByZWNvZGUoYWN0X2NvdmlkLCANCiAgICAgICAgICAgICJubyIgPSBGQUxTRSwgIk5vIiA9IEZBTFNFLCAiU2kiID0gVFJVRSwgInNpIiA9IFRSVUUsICJzw60iID0gVFJVRSwgIlPDrSIgPSBUUlVFKSkgJT4lIA0KICByZXBsYWNlX25hKGxpc3QocmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zID0gRkFMU0UsIGFjdF9jb3ZpZCA9IEZBTFNFKSkgDQoNCiMgcmVjb2RpbmcgZXN0YXR1c19hY3RpdmlkYWQNCmFjdDEkZXN0YXR1c19hY3RpdmlkYWQgPC0gYWN0MSRlc3RhdHVzX2FjdGl2aWRhZCAlPiUgDQogIHN0cl9yZXBsYWNlX2FsbChjKCJFbiBlamVjdWNpb24iID0gImVqZWN1Y2lvbiIsIA0KICAgICAgICAgICAgICAgICAgICAiZW4gZWplY3VjacOzbiIgPSAiZWplY3VjaW9uIiwgDQogICAgICAgICAgICAgICAgICAgICJlbiBFamVjdWNpw7NuIiA9ICJlamVjdWNpb24iLA0KICAgICAgICAgICAgICAgICAgICAiRW4gZWplY3VjacOzbiIgPSAiZWplY3VjaW9uIiwNCiAgICAgICAgICAgICAgICAgICAgIkVuIEVqZWN1Y2nDs24iID0gImVqZWN1Y2lvbiIsDQogICAgICAgICAgICAgICAgICAgICJmaW5hbGl6YWRhIiA9ICJmaW5hbGl6YWRhIiwNCiAgICAgICAgICAgICAgICAgICAgIkZpbmFsaXphZGEiID0gImZpbmFsaXphZGEiKSkNCg0KIyBjcmVhdGUgYSBuZXcgdmFyaWFibGUgb2YgbGFzdCBkYXkgb2YgbW9udGggb25seSANCmFjdDEkbWVzX3NvbG8gPC0gY2VpbGluZ19kYXRlKGFjdDEkbWVzX3JlcG9ydGFkbywgIm1vbnRoIikgLSBkYXlzKDEpDQpgYGANCg0KJm5ic3A7DQoNCiMjIDMuIENsZWFuaW5nIGxvY2F0aW9ucyANCg0KIyMjIDNhLiBSZWFkIGluIGBsb2NhdGlvbnMuY3N2YA0KDQo+IEFuZCBjaGVjayBpZiB5b3UgbmVlZCB0byB1cGRhdGUgaXQuIA0KDQpgYGB7ciByZWFkLWxvY2F0aW9ucywgZWNobz1UUlVFfQ0KbG9jYXRpb25zIDwtIHJlYWRfY3N2KCJsb2NhdGlvbnMuY3N2IikgJT4lDQogIG11dGF0ZShlc3RhZG8gICAgPSBybV9hY2NlbnQoc3RyX3RvX3VwcGVyKGVzdGFkbykpLCAjIGp1c3QgdG8gbWFrZSBzdXJlIA0KICAgICAgICAgbXVuaWNpcGlvID0gcm1fYWNjZW50KHN0cl90b191cHBlcihtdW5pY2lwaW8pKSwNCiAgICAgICAgIHBhcnJvcXVpYSA9IHJtX2FjY2VudChzdHJfdG9fdXBwZXIocGFycm9xdWlhKSksDQogICAgICAgICB1YmljYWNpb24gPSBybV9hY2NlbnQoc3RyX3RvX3VwcGVyKHViaWNhY2lvbikpKQ0KYGBgDQoNCj4gTWF5YmUgd2Ugc2hvdWxkIGFkZCBuZXcgcGNvZGVzIGZvciAidG9kbyBtdW5pY2lwaW8iIGFuZCAgInRvZG8gZXN0YWRvIjsgd2lsbCB0aGV5IGJlIGFidXNlZD8NCg0KYGBge3IsIGxvY2F0aW9ucy1jaGVjaywgZWNobz1UUlVFfQ0KIyBzZWUgaWYgeW91IG5lZWQgdG8gdXBkYXRlIGxvY2F0aW9ucyANCiMgbmV3IGxvY2F0aW9ucyBub3QgaW4gbG9jYXRpb25zLmNzdiB3aWxsIGJlIGNhdWdodCBieSB0aGUgYW50aS1qb2luKCkNCiBsb2NhdGlvbnNfYWRkIDwtIGFjdDEgJT4lIA0KICAgc2VsZWN0KGVzdGFkbywgcGNvZGUxLCBtdW5pY2lwaW8sIHBjb2RlMiwgcGFycm9xdWlhLCBwY29kZTMsIHViaWNhY2lvbiwNCiAgICAgICAgICBsYXRpdHVkLCBsb25naXR1ZCkgJT4lIA0KICAgZGlzdGluY3QoKSAlPiUgDQogICBhbnRpX2pvaW4obG9jYXRpb25zLCBieSA9ICJ1YmljYWNpb24iKQ0KYGBgDQoNCg0KIyMjIDNiLiBTcGxpdHRpbmcgdGhlIGRhdGFzZXQgaW50byBjbGVhbiBhbmQgZGlydHkNCg0KYGBge3Igc3BsaXQtY2xlYW4tZGlydHksIGVjaG89VFJVRX0NCiMgc3BsaXR0aW5nIGludG8gdHdvIGRhdGFzZXRzLCBvbmUgY2xlYW4gb25lIGRpcnR5LiANCmFkbV9kaXJ0eSA8LSBhY3QxICU+JSANCiAgZmlsdGVyKGlzLm5hKGVzdGFkbykgfCBpcy5uYShwY29kZTEpIHwNCiAgICAgICAgIGlzLm5hKG11bmljaXBpbykgfCBpcy5uYShwY29kZTIpIHwNCiAgICAgICAgIGlzLm5hKHBhcnJvcXVpYSkgfCBpcy5uYShwY29kZTMpKQ0KDQphZG1fY2xlYW4gPC0gYWN0MSAlPiUgDQogIGZpbHRlcighaXMubmEoZXN0YWRvKSAmICFpcy5uYShwY29kZTEpICYNCiAgICAgICAgICFpcy5uYShtdW5pY2lwaW8pICYgIWlzLm5hKHBjb2RlMikgJg0KICAgICAgICAgIWlzLm5hKHBhcnJvcXVpYSkgJiAhaXMubmEocGNvZGUzKSkgDQoNCmBgYA0KDQojIyMgM2MuIEZpbGwgaW4gbWlzc2luZyB2YWx1ZXMgd2l0aCBgY29hbGVzY2UoKWANCg0KPiBUaGUgbG9jYXRpb25zIHJlZmVyZW5jZSBkYXRhc2V0IGlzIHVzZWQgdG8gY2xlYW4gYGFkbV9kaXJ0eWAgYW5kIHJld3JpdGUgaXQuIFRoZSBgZGlzdGluY3QoKWAgY2FsbCBhdCB0aGUgZW5kIGlzIHRvIGVuc3VyZSB0aGF0IG5vIGR1cGxpY2F0ZXMgYXJlIGluY2x1ZGVkIGFzIHRoZSBgbGVmdF9qb2luKClgIGFyZ3VtZW50IHdpbGwgcHJvZHVjZSBkdXBsaWNhdGVzIChzdGlsbCBub3Qgc3VyZSBob3cgdG8gY29udHJvbCB0aGlzKS4gQWZ0ZXIgd2hpY2gsIGBhZG1fY2xlYW5gIGFuZCBgYWRtX2RpcnR5YCBhcmUgY29tYmluZWQgaW50byBgYWN0MmAuDQoNCmBgYHtyIGZpbGwgaW4gbWlzc2luZyB2YWx1ZXMsIGVjaG89VFJVRX0NCiMgZmlsbGluZyBpbiBtaXNzaW5nIHZhbHVlcw0KYWRtX2RpcnR5IDwtIGFkbV9kaXJ0eSAlPiUgDQogIGxlZnRfam9pbihsb2NhdGlvbnMsIGJ5ID0gInViaWNhY2lvbiIpICU+JSANCiAgbXV0YXRlKGVzdGFkbyAgICA9IGNvYWxlc2NlKGVzdGFkby54LCBlc3RhZG8ueSksDQogICAgICAgICBwY29kZTEgICAgPSBjb2FsZXNjZShwY29kZTEueCwgcGNvZGUxLnkpLA0KICAgICAgICAgbXVuaWNpcGlvID0gY29hbGVzY2UobXVuaWNpcGlvLngsIG11bmljaXBpby55KSwNCiAgICAgICAgIHBjb2RlMiAgICA9IGNvYWxlc2NlKHBjb2RlMi54LCBwY29kZTIueSksDQogICAgICAgICBwYXJyb3F1aWEgPSBjb2FsZXNjZShwYXJyb3F1aWEueCwgcGFycm9xdWlhLnkpLA0KICAgICAgICAgcGNvZGUzICAgID0gY29hbGVzY2UocGNvZGUzLngsIHBjb2RlMy55KSkgJT4lIA0KICBzZWxlY3QoLWVzdGFkby54LCAtZXN0YWRvLnksIC1wY29kZTEueCwgLXBjb2RlMS55LA0KICAgICAgICAgLW11bmljaXBpby54LCAtbXVuaWNpcGlvLnksIC1wY29kZTIueCwgLXBjb2RlMi55LA0KICAgICAgICAgLXBhcnJvcXVpYS54LCAtcGFycm9xdWlhLnksIC1wY29kZTMueCwgLXBjb2RlMy55KSAlPiUgDQogIGRpc3RpbmN0KCkgIyByZW1vdmluZyBkdXBsaWNhdGUgcm93cyBmcm9tIHRoZSBqb2luIA0KDQojIGJpbmRfcm93cygpIGRvZXMgbm90IGNhcmUgYWJvdXQgY29sdW1uIHNlcXVlbmNlIA0KIyBidXQgcHV0IGFkbV9jbGVhbiBmaXJzdCBzbyB0aGF0IHRoZSBvcmlnaW5hbCBvcmRlciBpcyBwcmVzZXJ2ZWQNCmFjdDIgPC0gYmluZF9yb3dzKGFkbV9jbGVhbiwgYWRtX2RpcnR5KQ0KDQpgYGANCg0KIyMjIDNkLiBFcnJvciBjaGVja2luZyB0aGUgam9pbg0KPiBwcmludGluZyB0b3RhbCBiZW5lZmljaWFyaWVzIGZvciBgYWN0MWAgYW5kIGBhY3QyYCwgZm9sbG93ZWQgYnkgYG5yb3coKWAgZm9yIGJvdGguIA0KDQpgYGB7ciBqb2luLWVycm9yLWNoZWNrfQ0KIyBlcnJvciBjaGVja2luZw0KcmJpbmQoc3VtKGFjdDEkdG90YWxfYmVuZWZpY2lhcmlvcywgbmEucm0gPSBUUlVFKSwNCiAgICAgIHN1bShhY3QyJHRvdGFsX2JlbmVmaWNpYXJpb3MsIG5hLnJtID0gVFJVRSksDQogICAgICBucm93KGFjdDEpLA0KICAgICAgbnJvdyhhY3QyKSkNCmBgYA0KDQombmJzcDsNCg0KIyMgNC4gQmVuZWZpY2lhcnkgZGlzYWdncmVnYXRpb24gDQo+IFRoaXMgaXMgdG8gY2hlY2sgdGhhdCBgdG90YWxfYmVuZWZpY2lhcmlvc2AgaXMgZXF1YWwgdG8gdGhlIHN1bSBvZiBhbGwgZGlzYWdncmVnYXRlZCBjb2x1bW5zLiBGaXJzdCwgd2UgbXV0YXRlIGEgbmV3IGNvbHVtbiBieSBzdW1taW5nIGFsbCB0aGUgZGlzYWdncmVnYXRlZCBiZW5lZmljaWFyaWVzIGFuZCBjYWxsaW5nIGl0IGB0b3RhbF9iZW5fY2hlY2tgLiBUaGVuLCB3ZSBtdXRhdGUgYSBuZXcgY29sdW1uIGluIHRociBkYXRhc2V0IGNhbGxlZCBgbm9fZXNwX2JlbmAgb3IgYmVuZWZpY2lhcmlvcyBubyBlc3BlY2lmaWNhZG9zIHNvIHRoYXQgd2UgbWFpbnRhaW4gdGhlIHVuLWRpc2FnZ3JlZ2F0ZWQgYmVuZWZpY2lhcmllcyB3aXRob3V0IHBvbGx1dGluZyB0aGUgcmVzdCBvZiB0aGUgZGF0YXNldC4NCg0KYGBge3IgYmVuY2hlY2stYW5kLW5vLWVzcC1iZW4sIGVjaG89VFJVRSB9DQojIG11dGF0aW5nIGJlbmNoZWNrIGFuZCB1bnNwZWNpZmllZCBiZW5lZmljaWFyaWVzIGNvbHVtbnMgDQphY3QyIDwtIGFjdDIgJT4lIA0KICBtdXRhdGUodG90YWxfYmVuX2NoZWNrID0gc2VsZWN0KC4sIG1fMF8zOm1fbWF5b3Jlc19kZV8xOSkgJT4lICByb3dTdW1zKG5hLnJtID0gVFJVRSksIA0KICAgICAgICAgbm9fZXNwX2JlbiAgICAgID0gcm91bmQodG90YWxfYmVuZWZpY2lhcmlvcykgLSByb3VuZCh0b3RhbF9iZW5fY2hlY2spKSANCg0KYGBgDQoNCj4gTmV4dCwgd2UgcHJpbnQgcm93cyB3aGVyZSB0aGUgc3VtIG9mIGRpc2FnZ3JlZ2F0ZWQgYmVuZWZpY2lhcmllcyAoYHRvdGFsX2Jlbl9jaGVja2ApIGRvIG5vdCBtYXRjaCB0aGUgdG90YWxzIHJlcG9ydGVkIGluIHRoZSBgdG90YWxfYmVuZWZpY2lhcmlvc2AgY29sdW1uIHNvIHRoYXQgd2UgY2FuIHJldHVybiB0byB0aGUgcmVsZXZhbnQgcGFydGllcyBmb3IgZm9sbG93IHVwLiANCg0KYGBge3IgcHJpbnRpbmctYmVuY2hlY2t9DQojIHByaW50aW5nIHRoZSBiZW5jaGVjaw0KIyB0aGUgcm91bmQgaXMgbmVjZXNzYXJ5IGR1ZSB0byBmbG9hdGluZyBwb2ludCBhcml0aG1ldGljIGFzIHNvbWUgdmFsdWVzIGFyZQ0KIyBjbG9zZSBlbm91Z2ggdG8gMCB0byBiZSBpZ25vcmVkIGJ5IHVzIGJ1dCBub3QgYnkgUi4gDQojIG9ubHkgcGFuZGVyKCkgaWYgeW91IHdhbnQgdG8gcmVhZCB0aGUgaHRtbA0Kbm9fZXNwIDwtIGFjdDIgJT4lIA0KICBmaWx0ZXIocm91bmQodG90YWxfYmVuZWZpY2lhcmlvcykgIT0gcm91bmQodG90YWxfYmVuX2NoZWNrKSkgJT4lIA0KICBzZWxlY3Qob3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCBhY3RpdmlkYWRfZGVzYywgDQogICAgICAgICB1YmljYWNpb24sIHRvdGFsX2Jlbl9jaGVjaywgdG90YWxfYmVuZWZpY2lhcmlvcywgbm9fZXNwX2JlbikNCg0Ka2FibGUobm9fZXNwLCBjYXB0aW9uID0gIlVuZGlzYWdncmVnYXRlZCBiZW5lZmljaWFyaWVzIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAiYm9yZGVyZWQiLCBmb250X3NpemUgPSAxMikNCmBgYA0KDQombmJzcDsNCg0KIyMgNS4gT3V0cHV0cw0KDQojIyMgNWEuIENsZWFuZWQgd2lkZSB2ZXJzaW9uDQpgYGB7ciBkYXRlc3RhbXAsIGVjaG89VFJVRX0NCiMgdGltZXN0YW1wIGZvciBhbGwgdGhlIGZpbGVzIHRvIGJlIHdyaXR0ZW4gYmVsb3cNCm5vdyA8LSBTeXMudGltZSgpDQpgYGANCg0KPiBGb3Igc3VibWlzc2lvbnMgdG8gT0NIQSwgdGhpcyBvbmUgYWxpZ25zIHdpdGggdGhlaXIgZm9ybWF0DQoNCmBgYHtyIGNsZWFuZWQtd2lkZSwgZWNobz1UUlVFLCBldmFsPUZBTFNFfQ0KIyB0dXJuIG9uIGV2YWwgaWYgeW91IHdhbnQgdGhlIGZpbGUNCmZpbGVuYW1lX3dpZGUgPC0gcGFzdGUwKGZvcm1hdChub3csICIleSVtJWRfJUglTV8iKSwgIjVXX3dpZGUuY3N2IikNCndyaXRlX2NzdihhY3QyLCBmaWxlbmFtZV93aWRlKQ0KYGBgDQoNCiMjIyA1Yi4gVW5pcXVlIGJlbmVmaWNpYXJpZXMNCg0KPiBUaGlzIHNlY3Rpb24gcGl2b3RzIHRoZSBkYXRhc2V0IGxvbmdlciBpbnRvIHRpZHkgZGF0YSwgd2l0aCBvbmUgb2JzZXJ2YXRpb24gcGVyIGluc3RhbmNlIG9mIGFnZSBhbmQgc2V4OyB0aGlzIGlzIG5lY2Vzc2FyeSBmb3IgZWFzeSBwbG90dGluZyBhbmQgYW5hbHlzaXMuIEFkZGl0aW9uYWxseSwgcm93cyB3aXRoIG5vIGJlbmVmaWNpYXJpZXMgYXJlIGZpbHRlcmVkIG91dC4gDQoNCj4gVGhlIGRhdGFzZXQgYHVfYmVuYCBpcyBjcmVhdGVkIGJ5IHRha2luZyB0aGUgaGlnaGVzdCBudW1iZXIgb2YgYmVuZWZpY2lhcmllcyBieSBhZ2UgYW5kIHNleCBncm91cCBieSBsb2NhdGlvbiBvZiBhbGwgbm9uLXJlY3VycmVudCBiZW5lZmljaWFyaWVzLiBUaGUgY29sdW1ucyBhcmUgdGhlbiBmaWx0ZXJlZCBkb3duIHRvIGNyZWF0ZSBhIG1vcmUgdXNhYmxlIGRhdGFzZXQuIFdlIHdpbGwgdXNlIHRoaXMgZGF0YXNldCBmb3IgYW55IG9wZXJhdGlvbnMgcmVsYXRlZCB0byB1bmlxdWUgYmVuZWZpY2lhcmllcyAoaW5kaXZpZHVhbHMpLCBpbmNsdWRpbmcgY29tcGFyaXNvbnMgd2l0aCBjZW5zdXMgZGF0YSB0byBkZXRlcm1pbmUgcmVhY2ggYW5kIGNvdmVyYWdlIGFzIHdlbGwgYXMgZ2VvZ3JhcGhpYyBhbmFseXNpcy4gV2UgZHJvcCBhY3Rpdml0eSBpbmZvcm1hdGlvbiBmcm9tIHRoaXMgZGF0YXNldCBhcyBpdCBvbmx5IGNvbnRhaW5zIHRoZSBtYXggb2YgcGVyIGRpc2FnZ3JlZ2F0aW9uIGdyb3VwIHBlciBsb2NhdGlvbiBhbnl3YXkuIA0KDQpgYGB7ciB1bmlxdWUtYmVuZmljaWFyaWVzLCBlY2hvPVRSVUV9DQojIHBpdm90aW5nIGxvbmdlciBhbmQgY3JlYXRpbmcgbmV3IGRhdGFmcmFtZQ0KdV9iZW4gPC0gYWN0MiAlPiUgDQogIHNlbGVjdCgtdF9mX2JlbiwgLXRvdGFsX2Jlbl9jaGVjaykgJT4lICMgcmVtZW1iZXIgdG8gZHJvcCB0aGVtDQogIHJlbG9jYXRlKG1lc19zb2xvKSAlPiUgIyBtb3ZlcyBtZXNfc29sbyB0byB0aGUgZmlyc3QgdmFyaWFibGUNCiAgcGl2b3RfbG9uZ2VyKG1fMF8zOm5vX2VzcF9iZW4sIA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZGVzYWdyZWdhY2lvbiIsIHZhbHVlc190byA9ICJiZW5lZmljaWFyaW9zIikgJT4lIA0KICBmaWx0ZXIocmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zID09IEZBTFNFKSAlPiUNCiAgZmlsdGVyKGJlbmVmaWNpYXJpb3MgIT0gMCkgJT4lICMgZW1wdHkgY2VsbHMgYXJlIDAgaW4gdGhlIDVXIHRhYmxlDQogIGdyb3VwX2J5KHViaWNhY2lvbiwgZGVzYWdyZWdhY2lvbikgJT4lIA0KICBzbGljZSh3aGljaC5tYXgoYmVuZWZpY2lhcmlvcykpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KG1lc19zb2xvLCBlc3RhZG8sIHBjb2RlMSwgbXVuaWNpcGlvLCBwY29kZTIscGFycm9xdWlhLCBwY29kZTMsIA0KICAgICAgICAgdWJpY2FjaW9uLCBsYXRpdHVkLCBsb25naXR1ZCwNCiAgICAgICAgIGRlc2FncmVnYWNpb24sIGJlbmVmaWNpYXJpb3MpDQpgYGANCg0KYGBge3Igd3JpdGluZy11LWJlbi1jc3YsIGVjaG89VFJVRSwgZXZhbD1GQUxTRX0NCiMgd3JpdGluZyBjc3Ygb2YgdV9iZW4gd2l0aCBkYXRlc3RhbXANCiMgdHVybiBvbiBldmFsIGlmIHlvdSB3YW50IHRoZSBmaWxlIA0KZmlsZW5hbWVfdV9iZW4gPC0gcGFzdGUwKGZvcm1hdChub3csICIleSVtJWRfJUglTV8iKSwgInVfYmVuLmNzdiIpDQp3cml0ZV9jc3YodV9iZW4sIGZpbGVuYW1lX3VfYmVuKQ0KYGBgDQoNCg0KIyMjIDVjLiBCZW5lZmljaWFyaWVzIGJ5IGFjdGl2aXR5DQoNCj4gVGhlIGRhdGFzZXQgYGFjdF9iZW5gIGlzIGZvciBhY3Rpdml0eS13aXNlIGFuYWx5c2lzLiBPbmx5IHRoZSByb3dzIG1hcmtlZCBhcyBgcmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zID09IEZBTFNFYCBoYXZlIGJlZW4gc2VsZWN0ZWQuIFRoZSBmaXJzdCBpbnN0YW5jZSBvZiByZWN1cnJpbmcgYmVuZWZpY2lhaXJlcyBpcyBtYXJrZWQgRkFMU0UsIHdpdGggYWxsIHN1YnNlcXVlbnQgZW50cmllcyBiZWluZyBtYXJrZWQgVFJVRS4gU2ltaWxhciB0byBgdV9iZW5gLCBpdCBoYXMgYWxzbyBiZWVuIHBpdm90ZWQgbG9uZ2VyIGludG8gdGlkeSBkYXRhLiANCg0KPiBQbGVhc2Ugbm90IHRoYXQgdGhlcmUgaXMgZG91YmxlIGNvdW50aW5nIGluIHRoaXMgZGF0YXNldCBhcyBzcGVjaWZpYyBiZW5lZmljaWFyaWVzIG1pZ2h0IGJlZW4gcmVhY2hlZCBieSBtb3JlIHRoYW4gb25lIGFjdGl2aXR5LiBGb3IgZ2VvZ3JhcGhpYyBhbmFseXNpcywgcGxlYXNlIHVzZSBgdV9iZW5gLg0KDQpgYGB7ciBiZW5lZmljaWFyaWVzLWJ5LWFjdGl2aXR5LCBlY2hvPVRSVUV9DQojIFRoaXMgaXMgdGhlIGRhdGFzZXQgZm9yIGJlbmVmaWNpYXJpZXMNCmFjdF9iZW4gPC0gYWN0MiAlPiUNCiAgc2VsZWN0KC10X2ZfYmVuLCAtdG90YWxfYmVuX2NoZWNrKSAlPiUgIyByZW1lbWJlciB0byBkcm9wIHRoZW0NCiAgcmVsb2NhdGUobWVzX3NvbG8pICU+JSAjIG1vdmVzIG1lc19zb2xvIHRvIHRoZSBmaXJzdCB2YXJpYWJsZQ0KICBmaWx0ZXIocmVjdXJyZW50ZV9iZW5lZmljaWFyaW9zID09IEZBTFNFKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKG1fMF8zOm5vX2VzcF9iZW4sIA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZGVzYWdyZWdhY2lvbiIsIHZhbHVlc190byA9ICJiZW5lZmljaWFyaW9zIikgJT4lIA0KICBmaWx0ZXIoYmVuZWZpY2lhcmlvcyAhPSAwKSAlPiUgIyBlbXB0eSBjZWxscyBhcmUgMCBpbiB0aGUgNVcgdGFibGUNCiAgZ3JvdXBfYnkodWJpY2FjaW9uLCBkZXNhZ3JlZ2FjaW9uKSAlPiUgDQogIHNlbGVjdChtZXNfc29sbywgbm9tYnJlX2RlbF9wcm95ZWN0bywgb3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCANCiAgICAgICAgIGVzdGFkbywgcGNvZGUxLCBtdW5pY2lwaW8sIHBjb2RlMiwgcGFycm9xdWlhLCBwY29kZTMsIA0KICAgICAgICAgdWJpY2FjaW9uLCBsYXRpdHVkLCBsb25naXR1ZCwNCiAgICAgICAgIGFjdGl2aWRhZF9jb2RpZ28sIGFjdGl2aWRhZF9kZXNjLCBhY3RfY292aWQsDQogICAgICAgICBkZXNhZ3JlZ2FjaW9uLCBiZW5lZmljaWFyaW9zKQ0KDQpgYGANCg0KDQpgYGB7ciB3cml0aW5nLWFjdC1iZW4tY3N2LCBlY2hvPVRSVUUsIGV2YWw9RkFMU0V9DQojIHdyaXRpbmcgY3N2IGFjdF9iZW4gd2l0aCBkYXRlc3RhbXANCiMgdHVybiBvbiBldmFsIGlmIHlvdSB3YW50IHRoZSBmaWxlIA0KZmlsZW5hbWVfYWN0X2JlbiA8LSBwYXN0ZTAoZm9ybWF0KG5vdywgIiV5JW0lZF8lSCVNXyIpLCAiYWN0X2Jlbi5jc3YiKQ0Kd3JpdGVfY3N2KGFjdF9iZW4sIGZpbGVuYW1lX2FjdF9iZW4pDQpgYGANCg0KIyMjIDVkLiBDb21wYXJpbmcgYHVfYmVuYCwgYGFjdF9iZW5gIGFuZCBkaWZmZXJlbmNlDQoNCj4gUGxlYXNlIG5vdGUgdGhhdCB0aGlzIHN0aWxsIGhhcyB0aGF0IHJhZGlvIG1lc3NhZ2luZyBhY3Rpdml0eSBsdW1wZWQgaW4gd2l0aCB0aGUgdG90YWxzLiANCg0KYGBge3IgY29tcGFyaW5nfQ0KDQpyYmluZCgoZm9ybWF0KHN1bSh1X2JlbiRiZW5lZmljaWFyaW9zKSwgYmlnLm1hcmsgPSAiLCIpKSwNCiAgICAgIChmb3JtYXQoc3VtKGFjdF9iZW4kYmVuZWZpY2lhcmlvcyksIGJpZy5tYXJrID0gIiwiKSksDQogICAgICAoZm9ybWF0KHN1bSh1X2JlbiRiZW5lZmljaWFyaW9zKSAtIHN1bShhY3RfYmVuJGJlbmVmaWNpYXJpb3MpLCBiaWcubWFyayA9ICIsIikpKQ0KYGBgDQoNCiZuYnNwOw0KDQojIEIuIFJlcG9ydGluZyBvbiB0aGUgNVcgZGF0YSANCg0KYGBge3IgcmVwb3J0LXNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyByZWFkIGluIGNlbnN1cyByZWZlcmVuY2UgZGF0YXNldA0KY2VuX3JlZiA8LSByZWFkX2V4Y2VsKCJjZW5zdXNfZGF0YV8yMDE5MTEyMi54bHN4Iiwgc2hlZXQgPSAiZGF0YSIpICU+JSANCiAgY2xlYW5fbmFtZXMoKSAlPiUNCiAgc2VsZWN0KGVzdGFkbywgcGNvZGUxLCBtdW5pY2lwaW8sIHBjb2RlMiwgcGFycm9xdWlhLCBwY29kZTMsIGZpZWxkX29mZmljZSwNCiAgICAgICAgIHBvYmxhY2lvbl90b3RhbF8yMDExLCB4XzIwMTlfcG9ibGFjaW9uX3BhcnJvcXVpYWxfdG90YWwsDQogICAgICAgICBoYW1fMjAxOV9hbWJpdG9zX2dlLCBoYW1fMjAxOV94eF9wb2JyZXphX2Vudl9wb3JfcGFycm9xdWlhLCANCiAgICAgICAgIGhhbV8yMDE5X3h4X3BvYmxhY2lvbl9wb2JyZV9wb3JfcGFycm9xdWlhLA0KICAgICAgICAgcG9ibGFjaW9uX2luZmFudGlsX21lbm9yX2RlXzEyX2Fub3MsIHBvYmxhY2lvbl9hZG9sZXNjZW50ZXNfZGVfMTJfYV8xN19hbm9zLA0KICAgICAgICAgcG9ibGFjaW9uX2RlXzE4X2Fub3NfeV9tYXMsIA0KICAgICAgICAgcG9ibGFjaW9uX3VyYmFuYV9wZXJjZW50LCBhcmVhX2ttMiwgZGVuc2lkYWRfcG9ibGFjaW9uYWxfcHBsX2ttMiwNCiAgICAgICAgIG1hdHJpY3VsYV8yMDE3X2VkdWNhY2lvbl9pbmljaWFsLCBtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fcHJpbWFyaWEsIA0KICAgICAgICAgbWF0cmljdWxhXzIwMTdfZWR1Y2FjaW9uX21lZGlhKQ0KDQojIGZpbHRlcmluZyBvdXQgUFJPTU9DSU9OIE1FTlNBSkVTIENMQVZFUyBQQVJBIExBIENPTVVOSURBRCBFU0NPTEFSDQpDQTEwNSA8LSBhY3RfYmVuICU+JSBmaWx0ZXIoYWN0aXZpZGFkX2NvZGlnbyA9PSAiQ0ExLjA1IikNCg0KIyBjcmVhdGluZyBkYXRhc2V0cyB3aXRob3V0IENBMS4wNSBhbmQNCiMgZm9yIGFjdF9iZW4sIHJlY29kaW5nIFVOSUNFRiBhbmQgbXV0YXRpbmcgc2hvcnQgYWN0aXZpdHkgZGVzY3JpcHRpb25zDQphY3RfYmVuMiA8LSBhY3RfYmVuICU+JSANCiAgZmlsdGVyKGFjdGl2aWRhZF9jb2RpZ28gIT0gIkNBMS4wNSIpICU+JSANCiAgbXV0YXRlKG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSA9IA0KICAgICAgICAgICBzdHJfcmVwbGFjZV9hbGwob3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJVTklDRUYgLSBGb25kbyBkZSBsYXMgTmFjaW9uZXMgVW5pZGFzIHBhcmEgbGEgSW5mYW5jaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVOSUNFRiIpKSAlPiUgDQogIG11dGF0ZShhY3RpdmlkYWRfc2hvcnQgPSByZWNvZGUoYWN0aXZpZGFkX2NvZGlnbywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBMS4wMSA9ICIxLjAxX3JlaW5zZXJjaW9uIGVkdWNhdGl2YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBMS4wMiA9ICIxLjAyX25pdmVsYWNpb24geSBjYXBhY2l0YWNpb24iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQTEuMDMgPSAiMS4wM19raXRzIGVzY29sYXJlcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBMS4wNCA9ICIxLjA0X2FsaW1lbnRhY2lvbiBlc2NvbGFyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ExLjA1ID0gIjEuMDVfcHJvbW9jaW9uIG1lbnNhamVzIGNsYXZlcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBMS4wNiA9ICIxLjA2X2Fwb3lvIHBzaWNvZWR1Y2F0aXZvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ExLjA3ID0gIjEuMDdfYWN0aXZpZGFkZXMgcmVjcmVhdGl2YXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQTIuMDggPSAiMi4wOF9lZHVjYWNpb24gYSBkaXN0YW5jaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQTIuMDkgPSAiMi4wOV9mb3JtYWNpb24gZG9jZW50ZXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQTIuMTAgPSAiMi4xMF9iZWNhcyBkb2NlbnRlcyIpKQ0KICAgICAgICAgICAgICAgICAgICANCnVfYmVuMiA8LSB1X2JlbiAlPiUgZmlsdGVyKCFzdHJfZGV0ZWN0KC4kdWJpY2FjaW9uLCAiXlJBRElPIikpDQpgYGANCg0KJm5ic3A7DQoNCj4gVGhpcyBpcyBhbiBlbnRpcmVseSBhdXRvbWF0ZWQgcmVwb3J0IC0tIGFsbCBjaGFydHMgYW5kIHRhYmxlcywgYXMgd2VsbCBhcyBhbGwgZmlndXJlcyB3aXRoaW4gdGhlIHJlcG9ydCBoYXZlIGJlZW4gZ2VuZXJhdGVkIGZyb20gdGhlIGRhdGEsIHdpdGggbm8gbWFudWFsIGlucHV0LiBUaGlzIHJlcG9ydCBtYWtlcyB1c2Ugb2YgdGhlIG91dHB1dHMgb2YgdGhlIGA1V19jbGVhbmluZ2Agc2VjdGlvbiBhYm92ZS4gVGhpcyBzZXQgb2YgNVcgZGF0YSBwZXJ0YWlucyB0byB0aGUgRWR1Y2F0aW9uIENsdXN0ZXIgaW4gVmVuZXp1ZWxhIGFuZCBoYXMgaGFkIHBhcnRuZXIgaW5mb3JtYXRpb24gcmVtb3ZlZC4gQ29kZSB3aWxsIG5vdCBiZSBzaG93biBpbiB0aGlzIHNlY3Rpb24gLS0geW91IGNhbiBkb3dubG9hZCB0aGUgUm1kIGF0IHRoZSB0b3AtbGVmdCBjb3JuZXIgb2YgdGhpcyBkb3VjdW1lbnQuICANCg0KJm5ic3A7DQoNCiMjIDEuIFN1bW1hcnkgb2YgYmVuZWZpY2lhcmllcyBieSBhY3Rpdml0eSwgd2l0aCBzZXggcmF0aW8NCg0KYGBge3Igc3VtbWFyeS1UQUJMRS1hY3Rpdml0eS1hbmQtc2V4fQ0KDQojIGFzIGEgbm90ZSwgaSBkb24ndCB0aGluayB5b3UgY2FuIHB1dCBhbiBzdHJfZGV0ZWN0IGluc2lkZSBhIHN1bW1hcmlzZQ0KYWN0X2JlbjIgJT4lIA0KICBtdXRhdGUoc2V4X2JlbiA9IGlmZWxzZShzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sICJebSIpLCAibWFsZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sICJeZiIpLCAiZmVtYWxlIiwgIm5vX2VzcCIpKSkgJT4lIA0KICBtdXRhdGUoYWN0aXZpZGFkID0gYWN0aXZpZGFkX2Rlc2MpICU+JSANCiAgZ3JvdXBfYnkoYWN0aXZpZGFkKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbCA9IHN1bShiZW5lZmljaWFyaW9zLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgbWFsZSA9IHN1bSgoYmVuZWZpY2lhcmlvc1tzZXhfYmVuID09ICJtYWxlIl0pKSwNCiAgICAgICAgICAgIGZlbWFsZSA9IHN1bSgoYmVuZWZpY2lhcmlvc1tzZXhfYmVuID09ICJmZW1hbGUiXSkpLA0KICAgICAgICAgICAgc2V4X3JhdGlvID0gcm91bmQoKG1hbGUvZmVtYWxlKSwgZGlnaXRzID0gMikpICU+JSANCiAgbXV0YXRlKHBlcmNlbnRfb2ZfdG90YWwgPSByb3VuZCgodG90YWwgLyBzdW0odG90YWwpICogMTAwKSwgZGlnaXRzID0gMikpICU+JSANCiAgcmVsb2NhdGUocGVyY2VudF9vZl90b3RhbCwgLmFmdGVyID0gdG90YWwpICU+JSANCiAgYXJyYW5nZShkZXNjKHRvdGFsKSkgJT4lIA0KICBwYW5kZXIoYmlnLm1hcmsgPSAiLCIsIHN0eWxlID0gInJtYXJrZG93biIpDQoNCmBgYA0KDQo+IEEgdG90YWwgb2YgX19gciBmb3JtYXQocm91bmQoc3VtKHVfYmVuMiRiZW5lZmljaWFyaW9zKSksIGJpZy5tYXJrID0gIiwiKWBfXyBpbmRpdmlkdWFscyBoYXZlIGJlZW4gcmVhY2hlZCB0byBkYXRlLiBJbiB0ZXJtcyBvZiBmcmVxdWVuY2llcyAoaW5jbHVzaXZlIG9mIGRvdWJsZSBjb3VudGluZyksIF9fYHIgZm9ybWF0KHN1bShhY3RfYmVuMiRiZW5lZmljaWFyaW9zKSwgYmlnLm1hcmsgPSAiLCIpYF9fIGhhdmUgYmVlbiByZWFjaGVkLiANCg0KPiBBZGRpdGlvbmFsbHksIHRoZSBfX2ByIGZvcm1hdChzdW0oQ0ExMDUkYmVuZWZpY2lhcmlvcyksIGJpZy5tYXJrID0gIiwiKWBfXyBiZW5lZmljaWFyeSBmcmVxdWVuY2llcyByZWFjaGVkIGJ5IHRoZSBhY3Rpdml0eSBQUk9NT0NJT04gTUVOU0FKRVMgQ0xBVkVTIFBBUkEgTEEgQ09NVU5JREFEIEVTQ09MQVIgaGF2ZSBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgdG90YWxzIGluIHRoaXMgcmVwb3J0IGFzIHRoZSBhY3Rpdml0eSBjb25zaXN0cyBvZiBzb2xlbHkgcmFkaW8gbWVzc2FnaW5nLiANCg0KJm5ic3A7DQoNCiMjIDIuIEJlbmVmaWNpYXJpZXMgYnkgYWdlIGdyb3VwDQoqZmlndXJlcyBhcmUgdW5pcXVlIGJlbmVmaWNpYXJpZXMvaW5kaXZpZHVhbHMqDQoNCmBgYHtyIFBMT1QtYmVuZWZpY2lhcmllcy1ieS1hZ2V9DQojIHRvIHJlb3JkZXIgdGhlIHBsb3QNCm9yZHZlYyA8LSBjKCIwLTMiLCAiMy02IiwgIjctMTIiLCAiMTItMTciLCAiMTgtMTkiLCAibWF5b3JfcXVlXzE5IikNCg0KIyBkZiBmb3IgdGhlIHBsb3QNCmFnZV91X2JlbiA8LSB1X2JlbjIgJT4lICMgaW1wb3J0YW50IHRvIHVzZSB1X2JlbiBoZXJlIA0KICBtdXRhdGUoYWdlX2JlbiA9IGNhc2Vfd2hlbigNCiAgICBzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sIjBfMyQiKSB+ICIwLTMiLA0KICAgIHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwiM182JCIpIH4gIjMtNiIsDQogICAgc3RyX2RldGVjdChkZXNhZ3JlZ2FjaW9uLCAiN18xMiQiKSB+ICI3LTEyIiwgDQogICAgc3RyX2RldGVjdChkZXNhZ3JlZ2FjaW9uLCAiMTJfMTckIikgfiAiMTItMTciLA0KICAgIHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwgIjE4XzE5JCIpIH4gIjE4LTE5IiwNCiAgICBzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sICJtYXlvcmVzX2RlXzE5JCIpIH4gIm1heW9yX3F1ZV8xOSIsIA0KICAgIFRSVUUgfiAibm9fZXNwIikpICU+JQ0KICBmaWx0ZXIoYWdlX2JlbiAhPSAibm9fZXNwIikgJT4lIA0KICBncm91cF9ieShhZ2VfYmVuKSAlPiUgDQogIHN1bW1hcmlzZShiZW5lZmljaWFyaW9zID0gc3VtKGJlbmVmaWNpYXJpb3MpKQ0KDQpnZ3Bsb3QoZGF0YSA9IGFnZV91X2JlbiwgYWVzKHggPSBmY3RfcmVvcmRlcihhZ2VfYmVuLCBvcmR2ZWMpLCB5ID0gYmVuZWZpY2lhcmlvcykpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICJjb3JuZmxvd2VyYmx1ZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6Y29tbWEoYmVuZWZpY2lhcmlvcykpLCB2anVzdCA9IC0wLjI1LCBzaXplID0gNCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gdW5pdF9mb3JtYXQodW5pdCA9ICJLIiwgc2NhbGUgPSAxZS0zLCBzZXAgPSAiIikpICsNCiAgeGxhYigiR3J1cG9zIHBvciBFZGFkIikgKyB5bGFiKCJCZW5lZmljaWFyaW9zIikgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkNCg0KYGBgDQoNCiZuYnNwOw0KDQojIyMgMmEuIEJlbmVmaWNpYXJpZXMgYnkgYWdlIGNvbXBhcmVkIHRvIDIwMTcgRW5yb2xsbWVudA0KDQpgYGB7ciBSRUYtbWF0cmljLWJlbn0NCiMgcmVmZXJlbmNlIGRmIGZvciB0aGUgdGFibGUgYW5kIHRleHQgYmVsb3csIHJlc3RydWN0dXJpbmcgZW5yb2xsbWVudCBkYXRhIGZyb20gY2VuX3JlZg0KbWF0cmljX2JlbiA8LSBjZW5fcmVmICU+JSANCiAgc2VsZWN0KG1hdHJpY3VsYV8yMDE3X2VkdWNhY2lvbl9pbmljaWFsLCBtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fcHJpbWFyaWEsIA0KICAgICAgICAgbWF0cmljdWxhXzIwMTdfZWR1Y2FjaW9uX21lZGlhKSAlPiUNCiAgcmVuYW1lKCIzLTYiID0gbWF0cmljdWxhXzIwMTdfZWR1Y2FjaW9uX2luaWNpYWwsDQogICAgICAgICAiNy0xMiIgPSBtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fcHJpbWFyaWEsDQogICAgICAgICAiMTItMTciID0gbWF0cmljdWxhXzIwMTdfZWR1Y2FjaW9uX21lZGlhKSAlPiUgDQogIHBpdm90X2xvbmdlcihldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gImFnZV9iZW4iLCB2YWx1ZXNfdG8gPSAibWF0cmljdWxhMjAxNyIsIA0KICAgICAgICAgICAgICAgdmFsdWVzX2Ryb3BfbmEgPSBUUlVFKSAlPiUgDQogIGdyb3VwX2J5KGFnZV9iZW4pICU+JSANCiAgc3VtbWFyaXNlKG1hdHJpY3VsYTIwMTcgPSBzdW0obWF0cmljdWxhMjAxNykpICU+JQ0KICBsZWZ0X2pvaW4oYWdlX3VfYmVuKSAlPiUgDQogIG11dGF0ZShwZXJjZW50X3RvdGFsID0gYmVuZWZpY2lhcmlvcy9tYXRyaWN1bGEyMDE3ICogMTAwKSAlPiUgDQogIHJlbG9jYXRlKGJlbmVmaWNpYXJpb3MsIC5hZnRlciA9IGFnZV9iZW4pICU+JSANCiAgcmVuYW1lKGBFZGFkIGdydXBvYCA9IGFnZV9iZW4pICU+JSANCiAgc2xpY2UoMiwzLDEpICAjIHJlYXJyYW5naW5nIHJvd3MNCiAgDQpgYGANCg0KPiBXaXRoIHJlZmVyZW5jZSB0byB0aGUgMjAxNyBNYXRyaWN1bGEgZGF0YXNldCwgd2UgY2FuIHNlZSB0aGF0IHRoZSBFZHVjYXRpb24gcHJvZ3JhbW1lIGhhcyByZWFjaGVkIGFuIG92ZXJhbGwgYXZlcmFnZSBvZiBfX2ByIHJvdW5kKHN1bShtYXRyaWNfYmVuJGJlbmVmaWNpYXJpb3MpLyhzdW0obWF0cmljX2JlbiRtYXRyaWN1bGEyMDE3KSkqMTAwKWAlX18gb2Ygc2Nob29sZ29pbmcgY2hpbGRyZW4gYWdlZCAzLTE3IG5hdGlvbndpZGUuIENoaWxkcmVuIGFnZWQgMy0xNyBjb25zaXR1dGUgX19gciByb3VuZChzdW0obWF0cmljX2JlbiRiZW5lZmljaWFyaW9zKS8oc3VtKHVfYmVuMiRiZW5lZmljaWFyaW9zKSkqMTAwKWAlX18gb2YgYWxsIFVOSUNFRiBiZW5lZmljaWFyaWVzLiANCg0KYGBge3IgVEFCTEUtbWF0cmljLWJlbn0NCnBhbmRlcihtYXRyaWNfYmVuLCBiaWcubWFyayA9ICIsIiwgc3R5bGUgPSAicm1hcmtkb3duIikNCmBgYA0KDQombmJzcDsNCg0KIyMgMy4gQ2hhbmdlcyBzaW5jZSBwcmV2aW91cyBtb250aA0KDQpgYGB7ciBSRUYtZm9yLXRleHQtY3VtdWxhdGl2ZS1kYXRhc2V0c30NCg0KIyBjcmVhdGluZyByZWZlcmVuY2UgZGZzIGZvciB0aGUgdGV4dCBhbmQgcGxvdCBiZWxvdw0KY3VtX3VfYmVuIDwtIHVfYmVuMiAlPiUgDQogIG11dGF0ZShtZXNfc29sbyA9IGFzLkRhdGUobWVzX3NvbG8pKSAlPiUgDQogIGFycmFuZ2UobWVzX3NvbG8pICU+JSANCiAgZ3JvdXBfYnkobWVzX3NvbG8pICU+JSANCiAgc3VtbWFyaXNlKHN1bV9iZW4gPSBzdW0oYmVuZWZpY2lhcmlvcykpICU+JSANCiAgbXV0YXRlKGN1bXVsYXRpdmUgPSBjdW1zdW0oc3VtX2JlbikpDQoNCmN1bV9hY3RfYmVuIDwtIGFjdF9iZW4yICU+JSANCiAgbXV0YXRlKG1lc19zb2xvID0gYXMuRGF0ZShtZXNfc29sbykpICU+JSANCiAgYXJyYW5nZShtZXNfc29sbykgJT4lIA0KICBncm91cF9ieShtZXNfc29sbykgJT4lIA0KICBzdW1tYXJpc2Uoc3VtX2JlbiA9IHN1bShiZW5lZmljaWFyaW9zKSkgJT4lIA0KICBtdXRhdGUoY3VtdWxhdGl2ZSA9IGN1bXN1bShzdW1fYmVuKSkNCmBgYA0KDQo+IFRoZSBudW1iZXIgb2YgaW5kaXZpZHVhbHMgcmVhY2hlZCBoYXMgaW5jcmVhc2VkIGJ5IF9fYHIgZm9ybWF0KGN1bV91X2JlblsxMSwzXSAtIGN1bV91X2JlblsxMCwzXSwgYmlnLm1hcmsgPSAiLCIpYF9fIGluIHRoZSBwYXN0IG1vbnRoLCByZWFjaGluZyBhIHRvdGFsIG9mIF9fYHIgZm9ybWF0KHJvdW5kKHN1bSh1X2JlbjIkYmVuZWZpY2lhcmlvcykpLCBiaWcubWFyayA9ICIsIilgX18uIFRoZSBudW1iZXIgb2YgYmVuZWZpY2lhcnkgZnJlcXVlbmNpZXMgcmVhY2hlZCBoYXMgaW5jcmVhc2VkIGJ5IF9fYHIgZm9ybWF0KGN1bV9hY3RfYmVuWzExLDNdIC0gY3VtX2FjdF9iZW5bMTAsM10sIGJpZy5tYXJrID0gIiwiKWBfXyBpbiB0aGUgc2FtZSBwZXJpb2QsIHJlYWNoaW5nIGEgdG90YWwgb2YgX19gciBmb3JtYXQoc3VtKGN1bV9hY3RfYmVuWzExLDNdKSwgYmlnLm1hcmsgPSAiLCIpYF9fLg0KDQpgYGB7ciAgbGluZS1QTE9ULWN1bXVsYXRpdmUtYmVuZWZpY2lhcmllc30NCnVfYmVuMiAlPiUgDQogIG11dGF0ZShtZXNfc29sbyA9IGFzLkRhdGUobWVzX3NvbG8pKSAlPiUgDQogIGFycmFuZ2UobWVzX3NvbG8pICU+JSANCiAgZ3JvdXBfYnkobWVzX3NvbG8pICU+JSANCiAgc3VtbWFyaXNlKHN1bV9iZW4gPSBzdW0oYmVuZWZpY2lhcmlvcykpICU+JSANCiAgbXV0YXRlKGN1bXVsYXRpdmUgPSBjdW1zdW0oc3VtX2JlbikpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVzX3NvbG8sIHkgPSBjdW11bGF0aXZlKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OmNvbW1hKGN1bXVsYXRpdmUpKSwgdmp1c3QgPSAtMC4yNSwgaGp1c3QgPSAxLCBzaXplID0gMykgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJWItJVkiLCBkYXRlX2JyZWFrcyA9ICIxIG1vbnRoIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjp1bml0X2Zvcm1hdCh1bml0ID0gIksiLCBzY2FsZSA9IDFlLTMsIHNlcCA9ICIiKSwNCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgwLDk1MDAwMCwgYnkgPSAyMDAwMDApKSArICMgd2hhdCBpcyB0aGlzIGJyZWFrcyBkb2luZz8NCiAgeGxhYigiTWVzIFJlcG9ydGFkbyIpICsgeWxhYigiQmVuZWZpY2lhcmlvcyAoY3VtdWxhdGl2bykiKQ0KYGBgDQoNCiZuYnNwOw0KDQojIyMgM2EuIFByb2dyZXNzIGJ5IGFjdGl2aXR5IGJ5IG1vbnRoDQoqbW91c2Ugb3ZlciB0byBzZWUgZGV0YWlscyoNCg0KDQpgYGB7ciBsaW5lLVBMT1RMWS1wcm9ncmVzcy1ieS1hY3Rpdml0eSwgZmlnLndpZHRoPTl9DQphY3RfbGluZXMgPC0gYWN0X2JlbjIgJT4lIA0KICBtdXRhdGUobWVzX3NvbG8gPSBhcy5EYXRlKG1lc19zb2xvKSkgJT4lIA0KICBncm91cF9ieShhY3RpdmlkYWRfc2hvcnQsIG1lc19zb2xvKSAlPiUgDQogIHN1bW1hcmlzZShjdW11bGF0aXZlID0gc3VtKGJlbmVmaWNpYXJpb3MpKSAlPiUgDQogIG11dGF0ZShjdW11bGF0aXZlID0gcm91bmQoY3Vtc3VtKGN1bXVsYXRpdmUpKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZXNfc29sbywgeSA9IGN1bXVsYXRpdmUsIGNvbG91ciA9IGFjdGl2aWRhZF9zaG9ydCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAwLjcpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiViLSVZIiwgZGF0ZV9icmVha3MgPSAiMSBtb250aCIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHVuaXRfZm9ybWF0KHVuaXQgPSAiSyIsIHNjYWxlID0gMWUtMywgc2VwID0gIiIpLCANCiAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9IGMoMCwgNTAwMDAwKSkgKw0KICB4bGFiKCIiKSArIHlsYWIoIkJlbmVmaWNpYXJpb3MiKSArDQogIHNjYWxlX2NvbG91cl9kaXNjcmV0ZShuYW1lID0gIkFjdGl2aWRhZCIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSkgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMiwgYnlyb3cgPSBUUlVFKSkNCg0KZ2dwbG90bHkoYWN0X2xpbmVzLCB0b29sdGlwID0gYygieCIsICJ5IiwgImNvbG91ciIpKSAlPiUgDQogIGxheW91dChzaG93bGVnZW5kID0gVFJVRSwgbGVnZW5kID0gbGlzdChmb250ID0gbGlzdChzaXplID0gNikpKSAlPiUgDQogICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkNCmBgYA0KPiBQcm9ncmVzcyBpbiByZWNlbnQgbW9udGhzIGhhcyBsYXJnZWx5IGJlZW4gZHVlIHRvIHRoZSBkaXN0cmlidXRpb24gb2YgZWR1Y2F0aW9uIGtpdHMgYW5kIGRpc3RhbmNlIGxlYXJuaW5nLiANCg0KJm5ic3A7DQoNCiMjIDQuIFN1bW1hcmllcyBieSBnZW9ncmFwaHkNCg0KIyMjIDRhLiBCZW5lZmljaWFyaWVzIGJ5IHN0YXRlDQoNCmBgYHtyIFBMT1QtYmVuZWZpY2lhaXJpZXMtYnktc3RhdGV9DQp1X2JlbjIgJT4lIA0KICBncm91cF9ieShlc3RhZG8pICU+JSANCiAgc3VtbWFyaXNlKGJlbmVmaWNpYXJpb3MgPSBzdW0oYmVuZWZpY2lhcmlvcykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfcmVvcmRlcihlc3RhZG8sIGJlbmVmaWNpYXJpb3MsIC5kZXNjID0gVFJVRSksIA0KICAgICAgICAgICAgIHkgPSBiZW5lZmljaWFyaW9zKSkgKw0KICBnZW9tX2NvbChmaWxsID0gImNvcm5mbG93ZXJibHVlIikgKw0KICB5bGltKDAsIDg1MDAwMCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpjb21tYShiZW5lZmljaWFyaW9zLCBhY2N1cmFjeSA9IDEpKSwgDQogICAgICAgICAgICB2anVzdCA9IC0wLjI1LCBoanVzdCA9IDAuMDUsIHNpemUgPSAzLCBhbmdsZSA9IDMwKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSB1bml0X2Zvcm1hdCh1bml0ID0gIksiLCBzY2FsZSA9IDFlLTMsIHNlcCA9ICIiKSwgDQogICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDAsIDIwMDAwMCkpICsNCiAgeGxhYigiIikgKyB5bGFiKCJCZW5lZmljaWFyaW9zIikgKyANCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQombmJzcDsNCg0KYGBge3IgUkVGLWZvci11YmljYWNpb24tdGV4dH0NCm1pcmFfenVsIDwtIHVfYmVuMiAlPiUgZmlsdGVyKGVzdGFkbyA9PSAiTUlSQU5EQSIgfCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzdGFkbyA9PSAiWlVMSUEiKQ0KYGBgDQoNCiMjIyA0Yi4gTnVtYmVyIG9mIHNjaG9vbHMgYnkgc3RhdGUNCj4gQSB0b3RhbCBvZiBfX2ByIGZvcm1hdChuX2Rpc3RpbmN0KHVfYmVuMiR1YmljYWNpb24pLCBiaWcubWFyayA9ICIsIilgX18gc2Nob29scyBoYXZlIGJlZW4gcmVhY2hlZCBieSBVTklDRUY7IF9fYHIgcm91bmQoKG5fZGlzdGluY3QobWlyYV96dWwkdWJpY2FjaW9uKSkgLyAobl9kaXN0aW5jdCh1X2JlbjIkdWJpY2FjaW9uKSkgKiAxMDApYCVfXyBhcmUgZnJvbSBNaXJhbmRhIGFuZCBadWxpYSBhbG9uZS4gDQoNCmBgYHtyIFBMT1Qtb2YtdWJpY2FjaW9uLWJ5LXN0YXRlfQ0KdV9iZW4yICU+JSANCiAgZ3JvdXBfYnkoZXN0YWRvKSAlPiUgDQogIGRpc3RpbmN0KHViaWNhY2lvbikgJT4lIA0KICBzdW1tYXJpc2UodWJpY2FjaW9uID0gbigpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZjdF9yZW9yZGVyKGVzdGFkbywgdWJpY2FjaW9uLCAuZGVzYyA9IFRSVUUpLCB5ID0gdWJpY2FjaW9uKSkgKw0KICBnZW9tX2NvbChmaWxsID0gImNvcm5mbG93ZXJibHVlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQodWJpY2FjaW9uKSksIHZqdXN0ID0gLTAuMjUsIHNpemUgPSAzKSArIA0KICB4bGFiKCIiKSArIHlsYWIoIk51bWVybyBkZSBFc2N1ZWxhcyIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQoNCiZuYnNwOw0KDQpgYGB7ciBSRUYtZm9yLWFsbF9tdW59DQojIGNyZWF0aW5nIHRoZSBhbGxfbXVuIGRmDQojIGFsbF9tdW4gaXMgb25lIG9icyBwZXIgcGNvZGUyDQphbGxfbXVuIDwtIHVfYmVuMiAlPiUgDQogIG11dGF0ZShpc19tYXRyaWMgPSBjYXNlX3doZW4oICMgZm9yIGJlbmVmaWNpYXJpZXMgYWdlZCAzLTE3DQogICAgICAgIHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwiM182JCIpIH4gIm1hdHJpYyIsDQogICAgICAgIHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwiN18xMiQiKSB+ICJtYXRyaWMiLA0KICAgICAgICBzdHJfZGV0ZWN0KGRlc2FncmVnYWNpb24sIjEyXzE3JCIpIH4gIm1hdHJpYyIsDQogICAgICAgIFRSVUUgfiAibm9uX21hdHJpYyIpKSAlPiUgDQogIG11dGF0ZShiZW5lZmljaWFyaW9zXzNfMTcgPSBpZmVsc2UoaXNfbWF0cmljID09ICJtYXRyaWMiLCBiZW5lZmljaWFyaW9zLCAwKSkgJT4lIA0KICBncm91cF9ieShlc3RhZG8sIG11bmljaXBpbywgcGNvZGUyKSAlPiUgDQogIHN1bW1hcmlzZShiZW5lZmljaWFyaW9zID0gcm91bmQoc3VtKGJlbmVmaWNpYXJpb3MpKSwNCiAgICAgICAgICAgIGJlbmVmaWNpYXJpb3NfM18xNyA9IHJvdW5kKHN1bShiZW5lZmljaWFyaW9zXzNfMTcpKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGxlZnRfam9pbihhY3RfYmVuICU+JSAjIGJyaW5naW5nIGFjdGl2aXR5IGNvdW50cyBpbnRvIHVfYmVuDQogICAgICAgICAgICBncm91cF9ieShwY29kZTIpICU+JSANCiAgICAgICAgICAgIHN1bW1hcmlzZShhY3RfdHlwZXMgPSBuX2Rpc3RpbmN0KGFjdGl2aWRhZF9jb2RpZ28pKSkgJT4lIA0KICByaWdodF9qb2luKGNlbl9yZWYgJT4lICMgZm9yIGJyaW5naW5nIG1hdHJpY3VsYTIwMTcgaW50byBhbGxfbXVuDQogICAgICAgICAgICBwaXZvdF9sb25nZXIoY29scyA9IGMoIm1hdHJpY3VsYV8yMDE3X2VkdWNhY2lvbl9pbmljaWFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fcHJpbWFyaWEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtYXRyaWN1bGFfMjAxN19lZHVjYWNpb25fbWVkaWEiKSwgDQogICAgICAgICAgICAgICAgICAgICBuYW1lc190byA9ICJhZ2VfYmVuIiwgdmFsdWVzX3RvID0gIm1hdHJpY3VsYTIwMTciLCANCiAgICAgICAgICAgICAgICAgICAgIHZhbHVlc19kcm9wX25hID0gVFJVRSkgJT4lIA0KICAgICAgICAgICAgc2VsZWN0KHBjb2RlMiwgYWdlX2JlbiwgbWF0cmljdWxhMjAxNykgJT4lIA0KICAgICAgICAgICAgZ3JvdXBfYnkocGNvZGUyKSAlPiUgDQogICAgICAgICAgICBzdW1tYXJpc2UobWF0cmljdWxhMjAxNyA9IHN1bShtYXRyaWN1bGEyMDE3KSkpICU+JSANCiAgbXV0YXRlKGNvdmVyYWdlX3BlcmNlbnQgPSByb3VuZChiZW5lZmljaWFyaW9zXzNfMTcgLyBtYXRyaWN1bGEyMDE3ICogMTAwKSkgJT4lIA0KICBtdXRhdGUoZXN0YWRvID0gZmN0X3Jlb3JkZXIoZXN0YWRvLCBiZW5lZmljaWFyaW9zLCAuZGVzYyA9IFRSVUUpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhiZW5lZmljaWFyaW9zKSkNCmBgYA0KDQojIyMgNGMuIFNjYXR0ZXJwbG90IG9mIG11bmljaXBhbGl0aWVzDQoqbG9nYXJpdGhtaWMgc2NhbGU7IGxhcmdlciBwb2ludHMgaW5kaWNhdGUgbW9yZSBiZW5lZmljaWFyaWVzIHJlYWNoZWQsIGRhcmtlciBibHVlcyBpbmRpY2F0ZSBtb3JlIGFjdGl2aXR5IHR5cGVzKiANCg0KKm1vdXNlIG92ZXIgbXVuaWNpcGFsaXRpZXMgdG8gc2VlIGJlbmVmaWNpYXJpZXMgYW5kIGRpc3RpbmN0IGFjdGl2aXRpZXMqDQoNCj4gQSB0b3RhbCBvZiBfX2ByIG5fZGlzdGluY3QodV9iZW4yJHBjb2RlMilgX18gbXVuaWNpcGFsaXRpZXMgd2VyZSByZWFjaGVkIGJ5IHRoZSBVTklDRUYgRWR1Y2F0aW9uIHByb2dyYW1tZS4NCg0KYGBge3Igc2NhdHRlci1QTE9UTFktb2YtbXVuaWNpcGFsaXRpZXMtYnktc3RhdGUsIGZpZy53aWR0aD05fQ0KDQphbGxfbXVuX3BvaW50cyA8LSBhbGxfbXVuICU+JSANCiAgZ2dwbG90KGFlcyh0ZXh0ID0gbXVuaWNpcGlvLCB4ID0gZXN0YWRvLCB5ID0gYmVuZWZpY2lhcmlvcywgDQogICAgICAgICAgICAgY29sb3VyID0gYWN0X3R5cGVzKSkgKw0KICBnZW9tX3BvaW50KGFlcyhzaXplID0gYmVuZWZpY2lhcmlvcyksIGFscGhhID0gMC45KSArDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudChsb3cgPSAiYXp1cmU0IiwgaGlnaCA9ICJkYXJrYmx1ZSIpICsgI2ZpbmQgYSBiZXR0ZXIgY29sb3VyPw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCANCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGNvbW1hKSArDQogIHhsYWIoIiIpICsgeWxhYigiQmVuZWZpY2lhcmlvcyBBbGNhbnphZG9zIHBvciBNdW5pY2lwaW8iKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSANCg0KZ2dwbG90bHkoYWxsX211bl9wb2ludHMsIHRvb2x0aXAgPSBjKCJ0ZXh0IiwgInkiLCAiY29sb3VyIikpICU+JSANCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpDQoNCmBgYA0KDQombmJzcDsNCg0KIyMjIDRkLiBUb3AgMTAgbXVuaWNpcGFsaXRpZXMgYnkgcmVhY2ggYW5kIGNvdmVyYWdlDQoNCmBgYHtyIG11bmljaXBhbGl0aWVzLXRvcC1UQUJMRX0NCiMgdG9wIG11bmljaXBhbGl0aWVzIHRhYmxlDQp0b3BfbXVuIDwtIGFsbF9tdW4gJT4lIHNlbGVjdChlc3RhZG8sIG11bmljaXBpbywgYmVuZWZpY2lhcmlvcykgJT4lIHNsaWNlKDE6MTApDQoNCiMgdHJ5IHRvIG1ha2UgYSB0YWJsZSBvZiB0aGUgbW9zdCBvdmVyc3Vic2NyaWJlZCBtdW5pY2lwYWxpdGllcw0KdG9wX2NvdiA8LSBhbGxfbXVuICU+JSANCiAgYXJyYW5nZShkZXNjKGNvdmVyYWdlX3BlcmNlbnQpKSAlPiUgDQogIHNlbGVjdChlc3RhZG8sIG11bmljaXBpbywgY292ZXJhZ2VfcGVyY2VudCkgJT4lIHNsaWNlKDE6MTApDQoNCiMgdHdvIHRhYmxlcyBzaWRlIGJ5IHNpZGUNCmthYmxlKHRvcF9tdW4sIGNhcHRpb24gPSAiYnkgYmVuZWZpY2lhcmllcyIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gImJvcmRlcmVkIiwgZnVsbF93aWR0aCA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICBwb3NpdGlvbiA9ICJmbG9hdF9sZWZ0IiwgZm9udF9zaXplID0gMTIpDQprYWJsZSh0b3BfY292LCBjYXB0aW9uID0gImJ5IGNvdmVyYWdlIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAiYm9yZGVyZWQiLCBmdWxsX3dpZHRoID0gRkFMU0UsIA0KICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gImxlZnQiLCBmb250X3NpemUgPSAxMikNCmBgYA0KDQpgYGB7ciBSRUYtZm9yLXRleHQtYmVsb3d9DQojIHN1bSBvZiB0b3AgdGVuDQp0b3BfbXVuX3N1bSA8LSBhbGxfbXVuICU+JSANCiAgc2xpY2UoMToxMCkgJT4lIHN1bW1hcmlzZShzdW0gPSBzdW0oYmVuZWZpY2lhcmlvcywgbmEucm0gPSBUUlVFKSkNCg0KYWxsX211bl9zdW0gPC0gYWxsX211biAlPiUgDQogIHN1bW1hcmlzZShzdW0gPSBzdW0oYmVuZWZpY2lhcmlvcywgbmEucm0gPSBUUlVFKSkNCmBgYA0KDQo+IFRvZ2V0aGVyLCB0aGUgMTAgbXVuaWNpcGFsaXRpZXMgd2l0aCB0aGUgaGlnaGVzdCByZWFjaCAoYWJvdmUgbGVmdCkgZm9ybSBfX2ByIHJvdW5kKHRvcF9tdW5fc3VtIC8gYWxsX211bl9zdW0gKiAxMDApYCVfXyBvZiB0aGUgX19gciBmb3JtYXQocm91bmQoc3VtKHVfYmVuMiRiZW5lZmljaWFyaW9zKSksIGJpZy5tYXJrID0gIiwiKWBfXyBiZW5lZmljaWFyaWVzIHJlYWNoZWQuIFRoZSBhdmVyYWdlIGNvdmVyYWdlIG9mIHRoZSBzY2hvb2wtYWdlIHBvcHVsYXRpb24gaW4gdGhlIG11bmljaXBhbGl0aWVzIHdoZXJlIFVOSUNFRiBpcyBwcmVzZW50IGlzIF9fYHIgcm91bmQobWVhbihhbGxfbXVuJGNvdmVyYWdlX3BlcmNlbnQsIG5hLnJtID0gVFJVRSkpYCVfXy4gQ292ZXJhZ2UgcmVmZXJzIHRvIHRoZSBwZXJjZW50YWdlIG9mIGVucm9sbGVkIGNoaWxkcmVuIChhZ2VkIDMtMTcgeWVhcnMpIHJlYWNoZWQgYnkgVU5JQ0VGLiANCg0KJm5ic3A7DQoNCiMjIyA0ZS4gSGlzdG9ncmFtIG9mIENvdmVyYWdlDQoNCj4gQmVsb3cgaXMgYSBoaXN0b2dyYW0gb2YgbXVuY2lpcGFsaXRpZXMgd2hlcmUgVU5JQ0VGIGlzIHByZXNlbnQgc2hvd2luZyB0aGUgY292ZXJhZ2Ugb2YgZW5yb2xsZWQgY2hpbGRyZW4gKGFnZWQgMy0xNykuIE9mIG5vdGUsIHdlIGhhdmUgcmVhY2hlZCAxMCUgb3IgbGVzcyBvZiB0aGUgcG9wdWxhdGlvbiBpbiBfX2ByIHN1bShhbGxfbXVuJGNvdmVyYWdlX3BlcmNlbnQgPD0gMTAsIG5hLnJtID0gVFJVRSlgX18gb3V0IG9mIHRoZSBfX2ByIG5fZGlzdGluY3QodV9iZW4yJHBjb2RlMilgX18gaW4gd2hpY2ggd2Ugb3BlcmF0ZS4gVGhpcyBpcyBpbiBhZGRpdGlvbiB0byB0aGUgX19gciBzdW0oaXMubmEoYWxsX211biRjb3ZlcmFnZV9wZXJjZW50KSlgX18gd2hlcmUgbm8gVU5JQ0VGIEVkdWNhdGlvbiBhY3Rpdml0aWVzIGhhdmUgb2NjdXJyZWQuIA0KDQpgYGB7ciBQTE9ULWhpc3RvZ3JhbS1vZi1jb3ZlcmFnZX0NCmFsbF9tdW4gJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBjb3ZlcmFnZV9wZXJjZW50KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEwLCBjb2xvdXIgPSAiYmxhY2siLCBmaWxsID0gIndoaXRlIikgKw0KICBzdGF0X2JpbihiaW53aWR0aCA9IDEwLCBnZW9tID0gInRleHQiLCBhZXMobGFiZWwgPSAuLmNvdW50Li4pLCB2anVzdCA9IC0wLjUpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMTAsIDIwLCAzMCwgNDAsIDUwLCA2MCwgNzAsIDgwLCA5MCkpICsNCiAgeWxhYigiTnVtYmVyIG9mIG11bmljaXBhbGl0aWVzIikgKyB4bGFiKCJQZXJjZW50IG9mIGVucm9sbGVkIGNoaWxkcmVuICgzLTE3KSBjb3ZlcmVkIikNCg0KYGBgDQoNCiZuYnNwOw0KDQojIyA1LiBSZXBvcnRzIGFib3V0IHBhcnRuZXJzDQoNCiMjIyA1YS4gU3VtbWFyeSBieSBwYXJ0bmVyDQoNCmBgYHtyIFBMT1RMWS1zdGFja2VkLWJhci1wYXJ0bmVyLCBmaWcud2lkdGg9OX0NCiMgZm9yIHRoZSB0b3RhbHMgcGVyIHBhcnRuZXIgc2hvd3MgaW4gdGhlIGdlb21fdGV4dCBiZWxvdw0Kc3RhY2tfdGV4dCA8LSBhY3RfYmVuMiAlPiUgDQogIGdyb3VwX2J5KG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWwgPSBzdW0oYmVuZWZpY2lhcmlvcykpICU+JSANCiAgYXJyYW5nZShkZXNjKHRvdGFsKSkNCg0KIyB2ZWN0b3IgZm9yIG9yZGVyaW5nIG9mIHgtYXhpcyAocGFydG5lcnMpDQpvcmRfc29jIDwtIGMoIlVOSUNFRiIsICJTT0NJTyAxIiwgIlNPQ0lPIDIiLCAiU09DSU8gNCIsICJTT0NJTyA1IiwgIlNPQ0lPIDciLCAiU09DSU8gOCIsDQogICAgICAgICAgICAgIlNPQ0lPIDMiLCAiU09DSU8gMTAiLCAiU09DSU8gNiIpDQoNCiMgY3JlYXRpbmcgdGhlIHBsb3QNCnNvY19zdGFjayA8LSBhY3RfYmVuMiAlPiUgDQogIGdyb3VwX2J5KGFjdGl2aWRhZF9zaG9ydCwgb3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhKSAlPiUgDQogIHN1bW1hcmlzZShiZW5lZmljaWFyaW9zID0gcm91bmQoc3VtKGJlbmVmaWNpYXJpb3MpKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSwgDQogICAgICAgICAgICAgeSA9IGJlbmVmaWNpYXJpb3MpKSArDQogIGdlb21fY29sKGFlcyhmaWxsID0gYWN0aXZpZGFkX3Nob3J0KSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gdW5pdF9mb3JtYXQodW5pdCA9ICJLIiwgc2NhbGUgPSAxZS0zLCBzZXAgPSAiIiksIA0KICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCA0MDAwMDApKSArDQogIHhsYWIoIiIpICsgeWxhYigiQmVuZWZpY2lhcmlvcyIpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksDQogICAgICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC4xLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWUgPSAiQWN0aXZpZGFkIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IHN0YWNrX3RleHQsIGFlcyh5ID0gdG90YWwgKyA2MDAwLCBsYWJlbCA9IHNjYWxlczo6Y29tbWEodG90YWwpKSwgDQogICAgICAgICAgICBzaXplID0gMykgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IG9yZF9zb2MpDQoNCmdncGxvdGx5KHNvY19zdGFjaywgdG9vbHRpcCA9IGMoIngiLCAiZmlsbCIsICJ5IikpICU+JSANCiAgbGF5b3V0KGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSAiPGI+IG9yZ2FuaXphY2lvbiA8Yj4iKSkpICU+JSANCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpICU+JSANCiAgbGF5b3V0KHNob3dsZWdlbmQgPSBUUlVFLCBsZWdlbmQgPSBsaXN0KGZvbnQgPSBsaXN0KHNpemUgPSA2KSkpDQoNCmBgYA0KDQombmJzcDsNCg0KIyMjIDViLiBOdW1iZXIgb2YgYWN0aXZpdHkgdHlwZXMgaW1wbGVtZW50ZWQgYnkgZWFjaCBwYXJ0bmVyDQoNCmBgYHtyIFRBQkxFLXBhcnRuZXItYWN0aXZpdHktY291bnR9DQojIHRoaXMgaW5jbHVkZXMgQ0ExLjA1DQphY3RfYmVuICU+JSANCiAgbXV0YXRlKG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSA9IA0KICAgICAgICAgICBzdHJfcmVwbGFjZV9hbGwob3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJVTklDRUYgLSBGb25kbyBkZSBsYXMgTmFjaW9uZXMgVW5pZGFzIHBhcmEgbGEgSW5mYW5jaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVOSUNFRiIpKSAlPiUgDQogIHJlbmFtZShwYXJ0bmVyID0gb3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhKSAlPiUgDQogIGdyb3VwX2J5KHBhcnRuZXIpICU+JSANCiAgc3VtbWFyaXNlKGFjdF90eXBlcyA9IG5fZGlzdGluY3QoYWN0aXZpZGFkX2NvZGlnbykpICU+JSANCiAgYXJyYW5nZShkZXNjKGFjdF90eXBlcykpICU+JSANCiAgdCgpICU+JSANCiAgcGFuZGVyKCkNCg0KYGBgDQoNCiZuYnNwOw0KDQojIyMgNWMuIFBhcnRuZXJzJyBwcm9ncmVzcyBvdmVyIHRpbWUNCiptb3VzZSBvdmVyIGZvciBkZXRhaWxzKg0KDQpgYGB7ciBsaW5lLVBMT1RMWS1wYXJ0bmVycy1wcm9ncmVzcywgZmlnLndpZHRoPTl9DQoNCnNvY19saW5lIDwtIGFjdF9iZW4yICU+JSANCiAgbXV0YXRlKG1lc19zb2xvID0gYXMuRGF0ZShtZXNfc29sbykpICU+JSANCiAgZ3JvdXBfYnkob3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhLCBtZXNfc29sbykgJT4lIA0KICBzdW1tYXJpc2UoY3VtdWxhdGl2ZSA9IHJvdW5kKHN1bShiZW5lZmljaWFyaW9zKSkpICU+JSANCiAgbXV0YXRlKGN1bXVsYXRpdmUgPSBjdW1zdW0oY3VtdWxhdGl2ZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVzX3NvbG8sIHkgPSBjdW11bGF0aXZlLCBjb2xvdXIgPSBvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEpKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMC43KSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlYi0lWSIsIGRhdGVfYnJlYWtzID0gIjEgbW9udGgiKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSB1bml0X2Zvcm1hdCh1bml0ID0gIksiLCBzY2FsZSA9IDFlLTMsIHNlcCA9ICIiKSwgDQogICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDAsIDQxMDAwMCkpICsNCiAgeGxhYigiIikgKyB5bGFiKCJCZW5lZmljaWFyaW9zIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpLA0KICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQ0KDQpnZ3Bsb3RseShzb2NfbGluZSwgdG9vbHRpcCA9IGMoIngiLCAieSIsICJjb2xvdXIiKSkgJT4lIA0KICBsYXlvdXQobGVnZW5kID0gbGlzdCh0aXRsZSA9IGxpc3QodGV4dCA9ICI8Yj4gb3JnYW5pemFjaW9uIDxiPiIpKSkgJT4lIA0KICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkNCiAgDQpgYGANCg0KJm5ic3A7DQoNCiMjIyA1ZC4gU3VtbWFyeSB0YWJsZSBvZiBwYXJ0bmVycycgYWNoaWV2ZW1lbnRzDQoNCmBgYHtyIFRBQkxFLXBhcnRuZXJzLXN1bW1hcnl9DQphY3RfYmVuMiAlPiUgDQogIG11dGF0ZShzZXhfYmVuID0gaWZlbHNlKHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwgIl5tIiksICJtYWxlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHN0cl9kZXRlY3QoZGVzYWdyZWdhY2lvbiwgIl5mIiksICJmZW1hbGUiLCAibm9fZXNwIikpKSAlPiUgDQogIG11dGF0ZShhY3RpdmlkYWQgPSBhY3RpdmlkYWRfZGVzYykgJT4lIA0KICBncm91cF9ieShvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEpICU+JSANCiAgc3VtbWFyaXNlKG1hbGUgPSBzdW0oKGJlbmVmaWNpYXJpb3Nbc2V4X2JlbiA9PSAibWFsZSJdKSksDQogICAgICAgICAgICBmZW1hbGUgPSBzdW0oKGJlbmVmaWNpYXJpb3Nbc2V4X2JlbiA9PSAiZmVtYWxlIl0pKSwNCiAgICAgICAgICAgIHNleF9yYXRpbyA9IHJvdW5kKChtYWxlL2ZlbWFsZSksIGRpZ2l0cyA9IDIpLA0KICAgICAgICAgICAgYmVuZWZpY2lhcmlvcyA9IHN1bShiZW5lZmljaWFyaW9zLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIG11dGF0ZShwZXJjZW50X29mX3RvdGFsID0gcm91bmQoKGJlbmVmaWNpYXJpb3MgLyBzdW0oYmVuZWZpY2lhcmlvcykgKiAxMDApLCBkaWdpdHMgPSAyKSkgJT4lIA0KICBsZWZ0X2pvaW4oYWN0X2JlbiAlPiUgDQogICAgICAgICAgICAgIG11dGF0ZShvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEgPSANCiAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKG9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiVU5JQ0VGIC0gRm9uZG8gZGUgbGFzIE5hY2lvbmVzIFVuaWRhcyBwYXJhIGxhIEluZmFuY2lhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJVTklDRUYiKSkgJT4lIA0KICAgICAgICAgICAgICBncm91cF9ieShvcmdhbml6YWNpb25faW1wbGVtZW50YWRvcmEpICU+JSANCiAgICAgICAgICAgICAgc3VtbWFyaXNlKG11bmljaXBhbGl0aWVzID0gbl9kaXN0aW5jdChwY29kZTIpKSwgDQogICAgIGJ5ID0gIm9yZ2FuaXphY2lvbl9pbXBsZW1lbnRhZG9yYSIpICU+JSANCiAgcmVsb2NhdGUoYmVuZWZpY2lhcmlvcywgLmFmdGVyID0gb3JnYW5pemFjaW9uX2ltcGxlbWVudGFkb3JhKSAlPiUgDQogIHJlbG9jYXRlKHBlcmNlbnRfb2ZfdG90YWwsIC5hZnRlciA9IGJlbmVmaWNpYXJpb3MpICU+JSANCiAgYXJyYW5nZShkZXNjKGJlbmVmaWNpYXJpb3MpKSAlPiUgDQogIHBhbmRlcihiaWcubWFyayA9ICIsIiwgc3R5bGUgPSAicm1hcmtkb3duIikNCmBgYA0KDQombmJzcDsNCg0KIyMgNi4gTWFwcyBhbmQgcmVmZXJlbmNlIHRhYmxlDQoNCiZuYnNwOw0KDQojIyMgNmEuIE1hcHMgYXQgbXVuaWNpcGFsIGxldmVsDQoNCmBgYHtyIE1BUFMtbXVuLXJlYWNoZWQtYW5kLXBlcmNlbnQtcmVhY2hlZH0NCg0KIyByZWFkaW5nIGluIHNoYXBlZmlsZQ0KIyBxdWlldCA9IFRSVUUgaXMgdmVyeSBpbXBvcnRhbnQgaGVyZQ0KcGNvZGUyX3NoYXBlIDwtIHN0X3JlYWQoIkM6L1VzZXJzL1NlYW4gTmcvRG9jdW1lbnRzL1IvNVcvdm56X2FkbTJfc2hhcGVmaWxlcy92ZW5fYWRtYm5kYV9hZG0yXzIwMTgwNTAyLnNocCIsIHF1aWV0ID0gVFJVRSkgJT4lIA0KICByZW5hbWUocGNvZGUxID0gQURNMV9QQ09ERSwNCiAgICAgICAgIHBjb2RlMiA9IEFETTJfUENPREUpDQoNCiMgSSB0aGluayBwbG90bHkncyBzZWxlY3RvciB0b29sIGlzIG5vdCB2ZXJ5IGdvb2QuIG9yIG1heWJlIHRoZSBjZW50cm9pZHMNCiMgb2YgdGhlIHZlbl9hZG1ibmRhIGRhdGFzZXQgaXMgbm90IHZlcnkgZ29vZCwgYXQgbGVhc3Qgd2hlbiBpdCBjb21lcyB0byBjZW50cm9pZHMuIA0KDQojIHBsb3QgZm9yIGJlbmVmaWNpYXJpZXMgcmVhY2hlZCBieSBwY29kZTINCm11bl9iZW5fcGxvdCA8LSBhbGxfbXVuICU+JSANCiAgcmlnaHRfam9pbihwY29kZTJfc2hhcGUpICU+JSANCiAgc3RfYXNfc2YoKSAlPiUgDQogIGdncGxvdChhZXMoZmlsbCA9IGJlbmVmaWNpYXJpb3MpKSArDQogIGdlb21fc2Yoc2l6ZSA9IDAuMDEpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgZ2d0aXRsZSgiTnVtYmVyIG9mIGJlbmVmaWNpYXJpZXMgcmVhY2hlZCBieSBtdW5pY2lwYWxpdHkiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQodHJhbnMgPSB0cmFuc19yZXZlcnNlcigibG9nIiksIGJyZWFrcyA9IGMoMCwgMTAwLCAxMDAwLCAxMDAwMCwgODA0ODIpLA0KICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGNvbW1hLCBuYS52YWx1ZSA9ICJncmF5OTAiKSArDQogIHRoZW1lKGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC4zLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjksIDAuMSksDQogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KDQojIG1hcCBvZiBwZXJjZW50IG9mIGVucm9sbGVkIGNoaWRyZW4gY292ZXJlZCBieSBwY29kZTINCm11bl9wZXJjZW50X3Bsb3QgPC0gYWxsX211biAlPiUgDQogIHJpZ2h0X2pvaW4ocGNvZGUyX3NoYXBlKSAlPiUgDQogIHN0X2FzX3NmKCkgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IGNvdmVyYWdlX3BlcmNlbnQpKSsNCiAgZ2VvbV9zZihzaXplID0gMC4wMSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICBnZ3RpdGxlKCJQZXJjZW50IG9mIGVucm9sbGVkIGNoaWxkcmVuICgzLTE3KSByZWFjaGVkIGJ5IG11bmljaXBhbGl0eSIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsYWJlbHMgPSBjb21tYSwgdHJhbnMgPSAicmV2ZXJzZSIsIG5hLnZhbHVlID0gImdyYXk5MCIpKw0KICB0aGVtZShsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuMywgImNtIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45LCAwLjEpLA0KICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpDQoNCiMgdXNpbmcgcGF0Y2h3b3JrIHRvIHB1dCB0aGVtIHNpZGUgYnkgc2lkZSANCm11bl9iZW5fcGxvdCArIG11bl9wZXJjZW50X3Bsb3QgKyBwbG90X2xheW91dChuY29sID0gMikNCmBgYA0KDQombmJzcDsNCg0KIyMjIDZiLiBSZWZlcmVuY2UgdGFibGUgLS0gbXVuaWNpcGFsIGxldmVsDQoNCl9fdXNlIGBVTklDRUZfcHJlc2VudGAgdG8gZmlsdGVyIHRvIG11bmljaXBhbGl0aWVzIHdoZXJlIHRoZSBFZHVjYXRpb24gcHJvZ3JhbW1lIG9wZXJhdGVzX18NCg0KKkNBMDEuMDUgUHJvbW9jaW9uIGRlIG1lbnNhamVzIGNsYXZlcyBwYXJhIGxhIGNvbXVuaWRhZCBlc2NvbGFyIGlzIG5vdCBpbmNsdWRlZCoNCg0KYGBge3IgRFQtZGF0YXRhYmxlfQ0KDQojIGl0IHNob3dzIDMzNSwgc2hvdWxkbid0IHRoZXJlIGJlIDMzNj8gSSBiZXQgaXQncyBWYXJnYXMgYWdhaW4NCmFsbF9tdW4gJT4lIA0KICBtdXRhdGUoVU5JQ0VGX3ByZXNlbnQgPSBpZmVsc2UoaXMubmEoYmVuZWZpY2lhcmlvcyksIEZBTFNFLCBUUlVFKSkgJT4lIA0KICByZW5hbWUobm9fb2ZfYWN0aXZpdGllcyA9IGFjdF90eXBlcykgJT4lICMgSSBmZWVsIGxpa2UgeW91IHNob3VsZCBoYXZlIGRvbmUgdGhpcyBlYXJsaWVyDQogIGxlZnRfam9pbihjZW5fcmVmICU+JSAjIGFkZGl0aW9uYWwgY2Vuc3VzIHZhcmlhYmxlcw0KICAgICAgZ3JvdXBfYnkocGNvZGUyKSAlPiUgDQogICAgICBzdW1tYXJpc2UocG9vcl9wZXJzb25zID0gcm91bmQoc3VtKGhhbV8yMDE5X3h4X3BvYmxhY2lvbl9wb2JyZV9wb3JfcGFycm9xdWlhKSksDQogICAgICAgICAgICAgICAgdG90YWxfcG9wICAgID0gc3VtKHhfMjAxOV9wb2JsYWNpb25fcGFycm9xdWlhbF90b3RhbCkpICU+JSANCiAgICAgIG11dGF0ZShwb3ZlcnR5X2luY2lkZW5jZSA9IHJvdW5kKHBvb3JfcGVyc29ucyAvIHRvdGFsX3BvcCAqIDEwMCkpKSAlPiUgDQogIHNlbGVjdCghcGNvZGUyKSAlPiUNCiAgcmVsb2NhdGUoVU5JQ0VGX3ByZXNlbnQpICU+JSANCiAgcmVsb2NhdGUocG92ZXJ0eV9pbmNpZGVuY2UsIC5hZnRlciA9IGNvdmVyYWdlX3BlcmNlbnQpICU+JSANCiAgcmVsb2NhdGUobm9fb2ZfYWN0aXZpdGllcywgLmFmdGVyID0gcG92ZXJ0eV9pbmNpZGVuY2UpICU+JQ0KICBkYXRhdGFibGUoZmlsdGVyID0gInRvcCIsIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCwgc2Nyb2xsWCA9IFRSVUUpKSAlPiUgDQogIERUOjpmb3JtYXRTdHlsZShjb2x1bW5zID0gY29sbmFtZXMoLiksIGZvbnRTaXplID0gIjEycHQiKQ0KICANCmBgYA0KDQo=
>>>>>>> e20677e90f322826cdd69436c08e7989a6156c0b